الربيع - استبدال قيم خاصية Bean بقيم ملف خاصية جديدة
-
28-09-2019 - |
سؤال
لدي ملف خاصية واستخدام حامل مكان خاصية Spring ، أقوم بتعيين القيم على حبوب الربيع. الآن ، قد يتم تعديل ملف الخاصية هذا أثناء وقت التشغيل. هل هناك طريقة لتحديث خصائص حبوب الربيع مع قيمة الخاصية المعدلة حديثًا؟ على وجه الخصوص ، لدي العديد من حبوب المفرد؟ كيف يمكنني تحديثها بالقيم الجديدة؟ هل هناك بالفعل حل لهذا أو ينبغي ترميزه مخصصًا؟ إذا لم يكن موجودًا بالفعل ، فهل يمكن لأي شخص تقديم أفضل طريقة لتحقيق ذلك؟ شكرًا!
ملاحظة: طلبي هو تطبيق دفعة. أستخدم تكوين الكوارتز المستند إلى الربيع لتحديد جدولة الدُفعات.
المحلول
سأترك هذا للرجوع إليه ، لكن الإجابة المحدثة هي أسفل المقسم:
حسنا ConfigurableApplicationContext
الواجهة تحتوي على أ تحديث() الطريقة ، التي يجب أن تكون ما تريد ، ولكن السؤال هو: كيفية الوصول إلى هذه الطريقة. بغض النظر عن الطريقة التي تقوم بها ، ستبدأ بفاصوليا لها اعتماد من النوع ConfigurableApplicationContext
:
private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
this.context = ctx;
}
الآن الخياران الأساسيان اللذان أقترحانهما سيكونان على أي منهما
- استخدم ال إطار تنفيذ المهام ودع الفاصوليك يشاهد موارد العقار بانتظام ، مما يؤدي إلى تحديث ApplicationContext عندما يجد التغييرات أو
- يعرض الفول إلى 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);
}
}