Spring - 禁用特定Bean的Autoproxy

时间:2015-10-26 14:58:03

标签: spring spring-boot mockito aop spring-aop

为了模拟一些@Transactional带注释的类,我必须为它们禁用Springs` aop代理创建。

如何配置我的spring启动应用程序以完全排除特定spring bean的任何代理创建,或者如何删除此bean的所有建议?

已经建议

Subclassing e.g. InfrastructureAdvisorAutoProxyCreator,但会引发Class name [null] is not a known auto-proxy creator class错误。它似乎已在org.springframework.aop.config.AopConfigUtils中静态初始化。

2 个答案:

答案 0 :(得分:3)

作为一种解决方法,我使用弹簧AopUtils打开代理:

@SuppressWarnings("unchecked")
public <T> T unwrapProxy(T bean) {
    if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
        Advised advised = (Advised) bean;
        try {
            bean = (T) advised.getTargetSource().getTarget();
        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }
    return bean;
}

答案 1 :(得分:1)

不是原始问题的答案。但我认为你可以在这里使用@InjectMocks mockito作为解决方案。即使标记为@Transactional的类,它也应该有效。以下是关于主题的some questions。来自docs

  

@InjectMock 标记应在其上执行注射的字段。

     

允许速记模拟和间谍注射。   最大限度地减少重复模拟和间谍注射。   Mockito将尝试仅通过构造函数注入,setter注入或属性注入按顺序注入模拟,如下所述。如果以下任何一种策略失败,那么Mockito就不会报告失败;即你必须自己提供依赖。

     

构造函数注入;选择最大的构造函数,然后使用在测试中声明的模拟来解析参数。   注意:如果找不到参数,则传递null。如果需要非可模拟类型,则构造函数注入不会发生。在这些情况下,您必须自己满足依赖关系。

     

Property setter injection ; mocks将首先按类型解析,然后,如果有多个相同类型的属性,则通过匹配属性名称和模拟名称。

     

注1 :如果你有相同类型(或相同的删除)的属性,最好用匹配的属性命名所有@Mock带注释的字段,否则Mockito可能会感到困惑注射不会发生。

     

注2 :如果@InjectMocks实例之前没有初始化并且有一个no-arg构造函数,那么它将使用这个构造函数进行初始化。

     

现场注射; mocks将首先按类型解析,然后,如果有多个相同类型的属性,则通过匹配字段名称和模拟名称。

     

注1:如果你有相同类型(或相同的删除)的字段,最好用匹配的字段命名所有@Mock带注释的字段,否则Mockito可能会感到困惑注射不会发生。

     

注2 :如果@InjectMocks实例之前没有初始化并且有一个no-arg构造函数,那么它将使用这个构造函数进行初始化。