我设置了两个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>

simpleBean工作正常 - springDao没有。

SpringDao课程如下:

public class SpringDao extends JdbcDaoSupport {

private SimpleJdbcTemplate simpleJdbcTemplate;

public SimpleJdbcTemplate getSimpleJdbcTemplate() {

    if (simpleJdbcTemplate==null) {
        simpleJdbcTemplate= new SimpleJdbcTemplate(getDataSource());
    }
    return simpleJdbcTemplate;
}
    ...

我的单元测试是自动装配的:

@Autowired
@Qualifier("springDao")
protected SpringDao springDao;

第一个指示错误的是我收到此错误:

  

无法自动装配字段:。 。 。嵌套   例外是   java.lang.IllegalArgumentException异常

如果我注释掉@Qualifier注释并再次运行我的单元测试,我会得到这个:

  

没有预期的类型的唯一bean   单匹配bean但找到2:   [springDaoTarget,springDao]

这就是我的预期。

所以我将自动装配改为

@Autowired
@Qualifier("springDaoTarget")
protected SpringCustomerCapacityDao springDao;

并在我的单元测试中添加了以下内容:

        Object proxy = applicationContext.getBean("springDao");

    Assert.assertNotNull(proxy);
    Assert.assertTrue(proxy instanceof SpringDao);

测试实例失败了,(对我来说)意味着我的代理不是我的代理。

所以我很困惑。这是怎么回事?我该如何解决这个问题?

编辑以下是请求的springDaoTarget定义,这会让很多人失望:

<bean id="springDaoTarget" class="com.company.SpringDao">

有帮助吗?

解决方案

如果代理的目标至少实现了一个接口,那么Spring的默认行为是创建一个实现目标所有接口的JDK代理。这意味着它不会是目标类的子类。您可以通过强制创建CGLIB代理而不是目标的动态子类来覆盖它。

作为一般规则,如果您打算使用AOP但仅以有限的方式使用接口,则需要强制使用CGLIB。否则,您的容器中将有许多JDK代理,这些代理的类型与您加载的bean实现的类型不同。

见Cliff Meyers博客: Spring AOP:CGLIB或JDK Dynamic Proxies?

其他提示

一旦我弄明白,这很容易解决。 SpringDao不再继承JdbcDaoSupport,现在可以正常工作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top