戴着假发的程序员 出品
lookup-method标签
spring应用手册(第一部分)
lookup-method是spring实现的一种特殊的通过方法注入的方式。
我们看下面的案例:
我们有两个IAccountDAO接口的实现类:
接口:
/**
* @author 戴着假发的程序员
*
* @description
*/
public interface IAccountDAO {
public int save(String name);
}
两个实现类:
/**
* @author 戴着假发的程序员
* @description
*/
public class AccountDAO_mysql implements IAccountDAO {
@Override
public int save(String name){
System.out.println("AccountDAO_mysql-save->保存账户:"+name);
return 1;
}
}
/**
* @author 戴着假发的程序员
* @description
*/
public class AccountDAO_oracle implements IAccountDAO {
@Override
public int save(String name){
System.out.println("AccountDAO_oracle-save->保存账户:"+name);
return 1;
}
}
我们有一个抽象的service类,如下:
/**
* @author 戴着假发的程序员
*
* @description
*/
public abstract class AbstractAccountService {
//非抽象的保存方法
public int save(String name){
System.out.println("AbstractAccountService-save:"+name);
//调用抽象方法获取IAccountDAO对象
return getAccount().save(name);
};
//抽象方法获取IAccountDAO
public abstract IAccountDAO getAccount();
}
这里注意我们的service是一个抽象类,并没有属性IAccountDAO。 我们是通过一个抽象方法getAccount()获取IAccountDAO对象的。(看到这里肯定蒙圈,继续看下面的)
配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" 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.xsd">
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<!-- 注册accountDAO_mysql -->
<bean id="accountDAO_mysql" class="com.dk.demo1.dao.impl.AccountDAO_mysql"/>
<!--service配置 分别配置两个 -->
<bean id="accountService_mysql"
class="com.dk.demo1.service.AbstractAccountService">
<!-- 通过lookup-method 通知springgetAccount方法的返回值是 accountDAO_mysql-->
<lookup-method name="getAccount" bean="accountDAO_mysql"/>
</bean>
<bean id="accountService_oracle"
class="com.dk.demo1.service.AbstractAccountService">
<!-- 通过lookup-method 通知springgetAccount方法的返回值是 accountDAO_oracle-->
<lookup-method name="getAccount" bean="accountDAO_oracle"/>
</bean>
</beans>
测试:
@Test
public void testLookup(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext-demo4.xml");
AbstractAccountService bean1 = (AbstractAccountService) ac.getBean("accountService_mysql");
bean1.save("戴着假发的程序员");
AbstractAccountService bean2 = (AbstractAccountService) ac.getBean("accountService_oracle");
bean2.save("daizhejiafadechengxuyuan");
System.out.println(bean1);
System.out.println(bean1);
}
控制台
通过观察我们发现几个问题:
1、AbstractAccountService是一个抽象类,理论上spring无法创建对象。
2、getAccount是个抽象方法,理论上也无法调用。
我们仔细观察控制台输出的bean1和bean2对象,我们会发现这两个对象是通过CGLib产生的代理对象
com.dk.demo1.service.AbstractAccountServiceEnhancerBySpringCGLIBd688190a@799d4f69
com.dk.demo1.service.AbstractAccountServiceEnhancerBySpringCGLIBd688190a@799d4f69
所以Lookup-method的主要作用是:
1、通知spring当前类需要产生代理对象。
2、通知spring当前lookup-method标注的方法的返回值应该是bean属性指定的bean对象。
这样我们就会发现,我们可以通过一个抽象方法为一个抽象类中注入我们希望的bean对象。