我有两个Spring代理设置:
<bean id="simpleBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="simpleBeanTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>cacheInterceptor</value>
</list>
</property>
</bean>
<bean id="springDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="springDaoTarget"/>
<property name="interceptorNames">
<list>
<value>daoInterceptor</value>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
simpleBean工作正常 - springDao没有.
SpringDao类看起来像:
public class SpringDao extends JdbcDaoSupport {
private SimpleJdbcTemplate simpleJdbcTemplate;
public SimpleJdbcTemplate getSimpleJdbcTemplate() {
if (simpleJdbcTemplate==null) {
simpleJdbcTemplate= new SimpleJdbcTemplate(getDataSource());
}
return simpleJdbcTemplate;
}
...
Run Code Online (Sandbox Code Playgroud)
我的单元测试自动装配如下:
@Autowired
@Qualifier("springDao")
protected SpringDao springDao;
Run Code Online (Sandbox Code Playgroud)
并且第一个指示错误的是我收到此错误:
无法自动装配领域:...嵌套异常是java.lang.IllegalArgumentException
如果我注释掉@Qualifier注释并再次运行我的单元测试,我会得到:
没有类型的唯一bean ...期望的单个匹配bean但找到2:[springDaoTarget,springDao]
这就是我的预期.
所以我改变了我的自动装配
@Autowired
@Qualifier("springDaoTarget")
protected SpringCustomerCapacityDao springDao;
Run Code Online (Sandbox Code Playgroud)
并在我的单元测试中添加了以下内容:
Object proxy = applicationContext.getBean("springDao");
Assert.assertNotNull(proxy);
Assert.assertTrue(proxy instanceof SpringDao);
Run Code Online (Sandbox Code Playgroud)
而且testof的测试失败了,对我而言,这意味着我的代理并不是我的代理.
所以我很困惑.这是怎么回事?我怎样才能解决这个问题?
编辑 这里是请求的springDaoTarget定义,它将令许多人失望:
<bean id="springDaoTarget" class="com.company.SpringDao">
Run Code Online (Sandbox Code Playgroud)
如果代理的目标实现至少一个接口,那么Spring的默认行为是创建一个实现目标所有接口的JDK代理.这意味着它不会是目标类的子类.您可以通过强制创建CGLIB代理来覆盖它,而CGLIB代理是目标的动态子类.
作为一般规则,如果您打算使用AOP但仅以有限的方式使用接口,则需要强制使用CGLIB.否则,您的容器中将有许多JDK代理,这些代理的类型与您加载的bean实现的类型不同.
请参阅Cliff Meyers博客:Spring AOP:CGLIB或JDK Dynamic Proxies?
| 归档时间: |
|
| 查看次数: |
10816 次 |
| 最近记录: |