java - 不是的 Spring AOP 代理

标签 java spring aop

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

我的单元测试是这样 Autowiring 的:

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

出现问题的第一个迹象是我收到此错误:

Could not autowire field: . . . nested exception is java.lang.IllegalArgumentException

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

No unique bean of type ... expected single matching bean but found 2: [springDaoTarget, springDao]

这是我所期望的。

所以我将 Autowiring 更改为

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

并将以下内容添加到我的单元测试中:

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

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

并且 instanceof 测试失败了,这(对我而言)意味着我的代理并不是我真正的代理。

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

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

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

最佳答案

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

作为一般规则,如果您要使用 AOP 但仅以有限的方式使用接口(interface),您将希望强制使用 CGLIB。否则,您的容器中将有很多 JDK 代理,它们与您加载的 bean 实现类型不同。

请参阅 Cliff Meyers 博客:Spring AOP: CGLIB or JDK Dynamic Proxies?

关于java - 不是的 Spring AOP 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/305263/

相关文章:

java - getRemote().sendString(msg, new WriteCallback() {..}) 稳定吗?

java - 如何在不打开实际类文件的情况下查看 IntelliJ 中类的文件结构?

spring - Zuul或eureka将主机头设置为服务实例主机

java - Spring AOP : a proxy per advice?

c# - AspectPriority 的使用

java - 在Spring AOP中使用@JoinPoint调用Method.invoke()时“对象不是声明类的实例”

java - 过期的斐波那契兔子

java - ListView 上的属性缺少 Android 命名空间前缀

java - hibernate 获取非默认 mysql 端口的拒绝连接

java - SQL中请求随机行对应的Spring JPA方法名