1. lookup-method的应用:
1.1 子元素lookup-method 似乎不是很常用,但是在某些时候他的确是非常有用的属性,通常我们称它为 "获取器注入" .
引用 "Spring In Action " 中的一句话.
'获取器注入是一种特殊的方法注入,它是把一个方法声明为返回某种类型的bean,但实际上,返回的bean是配置文件里面配置的,此方法可用在设计一些可插拔的功能上,解除程序依赖'
1.2 我们来看看具体的应用:
1.2.1 首先我们创建一个父类,
1 public class Person { 2 3 public void showMe() { 4 System.out.println("I am person ,what about you ?"); 5 } 6 }
1.2.2 创建其子类,并覆盖其showMe()方法,
1 public class Theacher extends Person { 2 3 /* 4 * (non-Javadoc) 5 * 6 * @see test.lookup.method.entity.Person#showMe() 7 */ 8 @Override 9 public void showMe() { 10 System.out.println("I am a theacher,"); 11 } 12 }
1.2.3 创建调用方法
1 public abstract class GetBean { 2 3 private void showMe() { 4 this.getBean().showMe(); 5 } 6 7 public abstract Person getBean(); 8 9 }
1.2.4 创建测试类
1 public class Main { 2 3 public static String XML_PATH = "test\\lookup\\method\\entity\\applicationContxt.xml"; 4 5 public static void main(String[] args) { 6 try { 7 Resource resource = new ClassPathResource(XML_PATH); 8 XmlBeanFactory beanFactory = new XmlBeanFactory(resource); 9 GetBean bean = (GetBean) beanFactory.getBean("getBean"); 10 System.out.println(bean); 11 bean.getBean().showMe(); 12 } 13 catch (Exception e) { 14 e.printStackTrace(); 15 } 16 } 17 }
1.2.5 配置文件如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="getBean" class="test.lookup.method.entity.GetBean"> <lookup-method name="getBean" bean="teacher"/> </bean> <bean id="teacher" class="test.lookup.method.entity.Theacher"> </bean> <bean id="person" class="test.lookup.method.entity.Person"> </bean> </beans>
在配置文件中,我们看到了 lookup-method 子元素, 这个配置完成的功能就是动态地将teacher所代表的bean作为getBean的返回值,那么当我们的业务需要变更的或者需要替换的情况下我们只需要修改配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="getBean" class="test.lookup.method.entity.GetBean"> <lookup-method name="getBean" bean="person"/> </bean> <bean id="teacher" class="test.lookup.method.entity.Theacher"> </bean> <bean id="person" class="test.lookup.method.entity.Person"> </bean> </beans>
至此,我们已经初步了解了lookup-method的作用,这是我们去看看Spring 的源码;
1 /** 2 * Parse lookup-override sub-elements of the given bean element. 3 */ 4 public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) { 5 NodeList nl = beanEle.getChildNodes(); 6 for (int i = 0; i < nl.getLength(); i++) { 7 Node node = nl.item(i); 8 //仅当在Spring默认Bean的子元素下, 9 //且为<lookup-method 时有效 10 if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) { 11 Element ele = (Element) node; 12 // 获取要修饰的方法 13 String methodName = ele.getAttribute(NAME_ATTRIBUTE); 14 // 获取配置返回的Bean 15 String beanRef = ele.getAttribute(BEAN_ELEMENT); 16 LookupOverride override = new LookupOverride(methodName, beanRef); 17 override.setSource(extractSource(ele)); 18 overrides.addOverride(override); 19 } 20 } 21 }
上面的代码很熟悉,似乎与parseMetaElement的代码大同小异,
最大的区别就是在数据存储上面使用LookupOverride 类型的实体来进行数据承载,并记录在AbstractBeanDefinition中的methodOveride 属性中.