Lookup方法註射指容器能夠重寫容器中bean的抽象或具體方法,返回查找容器中其他bean的結果。 被查找的bean在上面描述的場景中通常是一個non-singleton bean (盡管也可以是一個singleton的)。Spring通過使用CGLIB庫在客戶端的類之上修改二進制碼, 從而實現上述的場景要求。
包含方法註入的客戶端類,必須按下面的形式的抽象(具體)定義方法:
protected abstract SingleShotHelper createSingleShotHelper();
如果方法不是抽象的,Spring就會直接重寫已有的實現。在XmlBeanFactory的情況下,你可以使用bean定義中的lookup-method 屬性來指示Spring去註入/重寫這個方法,以便從容器返回一個特定的bean。舉個例子說明:
<!– a stateful bean deployed as a protype (non-singleton) –>
<bean id="singleShotHelper class="…" singleton="false">
</bean>
<!– myBean uses singleShotHelper –>
<bean id="myBean" class="…">
<lookup-method name="createSingleShotHelper"
bean="singleShotHelper"/>
<property>
…
</property>
</bean>
當myBean需要一個新的singleShotHelper的實例的時候, 它就會調用它自己的createSingleShotHelper 方法。 值得註意的是:部署beans的人員必須小心地將singleShotHelper作為一個non-singleton部署 (如果確實需要這麼做)。如果它作為一個singleton(除非明確說明,否則缺省就是singletion)而部署, 同一個singleShotHelper實例將會每次被返回。
註意Lookup方法註射能夠同構造函數註射結合(對創建的bean提供可選的構造函數參數), 也可以同setter方法註射結合(在創建的bean之上設置屬性)。
Java代碼
public class UserDao {
public UserDao(){}
private String name = "";
public UserDao(String name) {
this.name = name;
}
public void create() {
System.out.println("create user from – " + name);
}
}
public abstract class UserManager {
public UserDao getUserDao() {
return new UserDao("UserManager.getUserDao()");
}
public void createUserDao() {
UserDao dao = getUserDao();
dao.create();
}
//方法註入所需要的方法,由spring提供實現
public abstract UserDao getSingleUserDao();
}
Xml代碼
<bean name="userManager" class="com.yoyousfot.spring.lookup.UserManager">
<lookup-method name="getSingleUserDao" bean="userDao"/>
</bean>
<bean name="userDao" class="com.yoyousfot.spring.lookup.UserDao">
<constructor-arg>
<value>lookup method</value>
</constructor-arg>
</bean>
通過這種機制我們可以在不修改原系統代碼的情況下,可以輕易的把UserDao換成別的類型相容的對象而不會影響原系統。Spring是使用CGLIB在字節碼級別動態實現出userManager的子類,並重寫getUserDao方法的方式來實現這個神奇的功能的。
作者“Jelly_JAVA博客”