Zamanında Bahar bean tanımını değiştirebilir miyim?
Aşağıdaki senaryoyu düşünün. Yapılandırılabilir olmalıdır olan bir bean ile Bahar uygulama bağlamında, DataSource
MailSender
bence. Değişken uygulama yapılandırma ayrı bir fasulye, hadi configuration
çağrı tarafından yönetilmektedir.
Yönetici şimdi yapılandırma değerlerini, e-posta adresi veya URL veritabanı gibi değiştirebilir ve yeniden başlatma, çalışma zamanında yapılandırılmış fasulye etmek istiyorum.
Sadece yapılandırılabilir bean özelliği yukarıda (ör ya da yapıcı enjeksiyon FactoryBean
tarafından oluşturulan) değiştir ama fasulye kendini yeniden yaratmak istemiyorum varsayalım.
Bunu başarmak için nasıl bir planın var mı? Tüm yapılandırma şey organize etmek için nasıl tavsiye almak için mutlu olurdum. Hiçbir şey sabit değildir. :-)
EDİT
İşler biraz açıklığa kavuşturmak için: yapılandırma güncelleştirme veya statik yapılandırma değerlerini enjekte etmek. sormuyorum Bir örnek çalışacağım:
<beans>
<util:map id="configuration">
<!-- initial configuration -->
</util:map>
<bean id="constructorInjectedBean" class="Foo">
<constructor-arg value="#{configuration['foobar']}" />
</bean>
<bean id="configurationService" class="ConfigurationService">
<property name="configuration" ref="configuration" />
</bean>
</beans>
Yapıcı enjeksiyon kullanan 8* *Bir fasulye var. Prototip bir kapsam ya da fabrika bir proxy kullanarak bir seçenek değildir bu yüzden çok pahalı olduğunu düşün, düşün DataSource
.
Yapmak istediğim şey her zaman yapılandırma (configurationService
constructorInjectedBean
yeniden ediliyor bean) ve uygulama bağlam bağımlı ve fasulye içine yeniden enjekte. güncelleştirilen.
Güvenle constructorInjectedBean
proxy büyü gerçekten bir seçenek değil bu yüzden bir arabirim kullanarak olduğunu varsayabiliriz.
Soruyu biraz daha net yapmış umarım.
CEVAP
Ben yaptım nasıl geçmişte: yapılandırma bağımlı olan hizmetleri çalışan sinek yaşam döngüsü bir arabirim uygulamak değiştirilebilir: İRefreshable:
public interface IRefreshable {
// Refresh the service having it apply its new values.
public void refresh(String filter);
// The service must decide if it wants a cache refresh based on the refresh message filter.
public boolean requiresRefresh(String filter);
}
Yapılandırma bir parça değiştirebilir, denetleyicileri (veya hizmet) yapılandırma değişti JMS konu (yapılandırma nesnenin adı temin) yayın. Mesaj bean tahrik sonra İRefreshable uygulayan tüm fasulye İRefreshable arayüzü sözleşme çağırır.
Bahar güzel şey otomatik olarak yenilenmesi gereken uygulama kapsamında herhangi bir hizmet, açıkça onları yapılandırmak için ihtiyacını ortadan kaldırarak tespit edebilirsiniz
public class MyCacheSynchService implements InitializingBean, ApplicationContextAware {
public void afterPropertiesSet() throws Exception {
Map<String, ?> refreshableServices = m_appCtx.getBeansOfType(IRefreshable.class);
for (Map.Entry<String, ?> entry : refreshableServices.entrySet() ) {
Object beanRef = entry.getValue();
if (beanRef instanceof IRefreshable) {
m_refreshableServices.add((IRefreshable)beanRef);
}
}
}
}
Bu yaklaşım, birçok uygulama sunucuları tüm o zaman farkında olması gereken yapılandırma, değişebilir, özellikle kümelenmiş bir uygulama iyi çalışıyor. Eğer değişiklikleri tetikleme mekanizması olarak JMX kullanmak istiyorsanız, JMX fasulye sonra JMS için herhangi bir niteliğini değiştirildiğinde konu yayını yapabilir.
Nasıl Twitter Bootstrap kalıcı bir kut...
Nasıl Eylem Bar eylemler dinamik olara...
Nasıl halka gizli bir Özü değiştirebil...
ReSharper Kısaltmalar Listesi: Nereye ...
Nasıl varsayılan kimlik bilgileri Visu...