الربيع - استبدال قيم خاصية Bean بقيم ملف خاصية جديدة

StackOverflow https://stackoverflow.com/questions/4084890

سؤال

لدي ملف خاصية واستخدام حامل مكان خاصية Spring ، أقوم بتعيين القيم على حبوب الربيع. الآن ، قد يتم تعديل ملف الخاصية هذا أثناء وقت التشغيل. هل هناك طريقة لتحديث خصائص حبوب الربيع مع قيمة الخاصية المعدلة حديثًا؟ على وجه الخصوص ، لدي العديد من حبوب المفرد؟ كيف يمكنني تحديثها بالقيم الجديدة؟ هل هناك بالفعل حل لهذا أو ينبغي ترميزه مخصصًا؟ إذا لم يكن موجودًا بالفعل ، فهل يمكن لأي شخص تقديم أفضل طريقة لتحقيق ذلك؟ شكرًا!

ملاحظة: طلبي هو تطبيق دفعة. أستخدم تكوين الكوارتز المستند إلى الربيع لتحديد جدولة الدُفعات.

هل كانت مفيدة؟

المحلول

سأترك هذا للرجوع إليه ، لكن الإجابة المحدثة هي أسفل المقسم:

حسنا ConfigurableApplicationContext الواجهة تحتوي على أ تحديث() الطريقة ، التي يجب أن تكون ما تريد ، ولكن السؤال هو: كيفية الوصول إلى هذه الطريقة. بغض النظر عن الطريقة التي تقوم بها ، ستبدأ بفاصوليا لها اعتماد من النوع ConfigurableApplicationContext:

private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
    this.context = ctx;
}

الآن الخياران الأساسيان اللذان أقترحانهما سيكونان على أي منهما

  1. استخدم ال إطار تنفيذ المهام ودع الفاصوليك يشاهد موارد العقار بانتظام ، مما يؤدي إلى تحديث ApplicationContext عندما يجد التغييرات أو
  2. يعرض الفول إلى JMX, ، مما يتيح لك تشغيل التحديث يدويًا.

بالإشارة إلى التعليقات: نظرًا لأنه من المستحيل تحديث السياق بأكمله ، فإن الإستراتيجية البديلة هي إنشاء فول مصنع خصائص وحقن ذلك في جميع الفاصوليا الأخرى.

public class PropertiesFactoryBean implements FactoryBean<Properties>{

    public void setPropertiesResource(Resource propertiesResource){
        this.propertiesResource = propertiesResource;
    }

    private Properties value=null;
    long lastChange = -1L;

    private Resource propertiesResource;

    @Override
    public Properties getObject() throws Exception{
        synchronized(this){
            long resourceModification = propertiesResource.lastModified();
            if(resourceModification != lastChange){
                Properties newProps = new Properties();
                InputStream is = propertiesResource.getInputStream();
                try{
                    newProps.load(is);
                } catch(IOException e){
                    throw e;
                } finally{
                    IOUtils.closeQuietly(is);
                }
                value=newProps;
                lastChange= resourceModification;
            }
        }
        // you might want to return a defensive copy here
        return value;
    }

    @Override
    public Class<?> getObjectType(){
        return Properties.class;
    }

    @Override
    public boolean isSingleton(){
        return false;
    }

}

يمكنك ضخ هذه الخصائص في جميع الفاصوليا الأخرى ، ومع ذلك ، يجب أن تكون حريصًا على استخدام نطاق النموذج الأولي دائمًا. هذا صعب بشكل خاص داخل حبوب المفرد ، يمكن العثور على حل هنا.

إذا كنت لا ترغب في ضخ أساليب البحث في كل مكان ، فيمكنك أيضًا حقن أ PropertyProvider فول مثل هذا:

public class PropertiesProvider implements ApplicationContextAware{

    private String propertyBeanName;
    private ApplicationContext applicationContext;

    public void setPropertyBeanName(final String propertyBeanName){
        this.propertyBeanName = propertyBeanName;
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException{
        this.applicationContext = applicationContext;
    }

    public String getProperty(final String propertyName){
        return ((Properties) applicationContext.getBean(propertyBeanName)).getProperty(propertyName);
    }

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top