天天看點

動态注冊bean到spring容器

原先的設計是通過已有的庫,将資料通過rmi寫入到遠端伺服器;現在有需求需要将支援多個,而且是自定義的遠端伺服器ip。

因為整個接口原先都是通過spring配置檔案,包括rmi的位址。同時,為了維護友善,不能直接将打好的jar包拿過來改,于是就采用了複制原有的bean definition,動态注冊新的bean到那個spring容器中。

首先需要擷取jar包中的spring容器,這裡需要将applicationcontext接口轉換成為真正的實作:defaultlistablebeanfactory,這樣才能使用其中的注冊和擷取beandefinition方法。

當要擷取bean的時候,首先先通過beanfactory的containsbean方法判斷是否已經有bean了,如果沒有,就繼續以下的步驟:

[cce lang=”java”]

rootbeandefinition remotedataserverclientdefinition =

(rootbeandefinition) beanfactory.getbeandefinition(base_bean_name); //擷取“模闆”bean的定義

rootbeandefinition remotedataserverclientnewdefinition =

new rootbeandefinition(remotedataserverclientdefinition); //深度複制

mutablepropertyvalues properties =

remotedataserverclientnewdefinition.getpropertyvalues(); //拿到原bean的屬性

beandefinitionholder defaultdatasourcefactorydefinitionholder = //這裡擷取屬性值

(beandefinitionholder) properties.getpropertyvalue(“servicefactory”).getvalue();

//下面省略,主要是對屬性值的修改和重新指派

//向bean factory中注冊新的bean,第一個參數是bean的名字,第二個參數是bean的定義

beanfactory.registerbeandefinition(udasclientbeanname, remotedataserverclientnewdefinition);

beanfactory.getbean(udasclientbeanname); //然後就可以從容器中拿bean了

[/cce]

整個過程非常簡單,其中注意一個地方,就是mutablepropertyvalues和spring配置檔案的關系。一個beandefinition的mutablepropertyvalues就是配置檔案中的一系列property标簽,可以擷取其中的value。如果property是一個bean,那個擷取過來的object對象,是beandefinitionholder對象,就是對屬性中引用bean的定義,以此類推。

比如,spring的配置檔案裡面有這樣的bean定義:

[cce lang=”xml”]

<bean id=”a” class=”x.y.z.a”>

<property name=”p1″ value=”test” />

<property name=”p2″>

<bean class=”x.y.z.b” />

</propery>

< /bean>

那麼通過getpropertyvalues()方法擷取到的mutablepropertyvalues就包含兩個屬性,可以通過mutablepropertyvalues的getpropertyvalue(“p1″)擷取到test這個值,getpropertyvalue(“p2″)擷取到的就是x.y.z.b這個類對應的beandefinition。

轉載自:https://coolex.info/blog/253.html