現在每個系統開發集成的開發框架和公用組件都太多瞭,而且每個組件都是用自己的配置,比如我們現在使用的一個單點登陸系統就是采用spring來配置管理的。其核心bean定義文件被打包在jar包中,當我們想替換其中的某一個bean定義時,又不太好直接修改bean定義文件,那樣會導致框架維護混亂。這裡,我們就可以使用spring中的bean前後處理器來進行動態替換,先說明場景哈。
有一個jar包,包含瞭一個xml文件,定義瞭自身的一系列bean。另外一個項目使用瞭這個jar包,但又想替換其中的一個bean,原來默認的bean是用配置文件來讀取信息,但現在想改成數據庫的模式。常規的方法是:
1、將xml文件拿出來,修改bean定以後再放到jar包內替換以前的;
2、直接將xml文件拿出來,刪除jar包中的,並將新的xml文件放在項目的classpath中
這兩個方法雖然可以解決問題,但不利於jar包本身的維護,如果升級瞭,那項目的改動就比較麻煩。這裡,我們其實完全可以采用spring的BeanPostProcessor來動態替換。
假設jar包中定義的xml文件中一個包含的bean定義如下:
<bean id="aa" class="cc.mzone.config.DefaultConfigImpl">…</bean>
其中DefaultConfigImpl這個bean就是我們要替換的對象,我們可以寫如下的類:
public class MyConfigImpl extends DefaultConfigImpl implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("defaultcfg")) { // do something return this; } return bean; }}
註意我們繼承瞭原始的DefaultConfigImpl,當然你也可以不繼承,單獨再寫一個也可以。同時實現瞭spring中的BeanPostProcessor,這個類是spring容器級別的處理器,可以在bean初始化前後做一些時間(這裡的初始化不是指類的初始化,而是相對bean的屬性設置而言的)。可以看到我們在postProcessBeforeInitialization這個方法中對bean名稱為defaultcfg的bean進行特殊處理,這裡我們是直接返回當前bean作為替換實例,從而也就實現瞭動態替換指定bean的效果,同時也不破壞原始的組件架構,可謂一舉兩得。
作者“thisisvoa的專欄”