子元素lookup-method似乎不是很常用,但是在某些时候它的确是非常有用的属性,通常我们称它为获取器注入。引用《spring in action》中的一句话:获取器注入是一种特殊的方法注入,它是把一个方法声明为返回某种类型的bean,但实际要返回的bean是在配置文件里面配置的,此方法可用在设计有些可插拔的功能上,解除程序依赖。
(1)首先创建一个父类
package com.pan.entity;
public class User {
public void showMe(){
System.out.println("User");
}
}
(2)创建子类覆盖showMe()方法
package com.pan.entity;
public class Teacher extends User {
@Override
public void showMe() {
System.out.println("teacher====");
}
}
(3)创建调用方法
package com.pan.entity;
public abstract class GetBean {
public abstract User getUser();
public void showMe(){
getUser().showMe();
}
}
(4)创建测试方法
package com.pan.test;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import com.pan.entity.GetBean;
import com.pan.entity.User;
@SuppressWarnings(value="all")
public class BeanTest {
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanTest.xml"));
@Test
public void bean(){
User user = (User) bf.getBean("user");
System.out.println(user.getClass().getName());
}
@Test
public void showMe(){
GetBean gb = bf.getBean(GetBean.class);
gb.showMe();
}
}
配置文件
<bean id="user" class="com.pan.entity.User" >
<meta key="testStr" value="aaaaaa"/>
</bean>
<bean id="getBean" class="com.pan.entity.GetBean">
<lookup-method name="getUser" bean="teacher"/>
</bean>
<bean id="teacher" class="com.pan.entity.Teacher"></bean>
在配置文件中,lookup-method配置一个name,bean。这个配置完成的功能是动态地将teacher所代表的bean作为getBean的返回值。
源码分析:
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
Element ele = (Element) node;
String methodName = ele.getAttribute(NAME_ATTRIBUTE);
String beanRef = ele.getAttribute(BEAN_ELEMENT);
LookupOverride override = new LookupOverride(methodName, beanRef);
override.setSource(extractSource(ele));
overrides.addOverride(override);
}
}
}