【问题标题】:Spring - disable Autoproxy for specific BeanSpring - 禁用特定 Bean 的 Autoproxy
【发布时间】:2016-01-25 17:42:57
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    Spring 现在通过提供 AopTestUtils 来提供解决方案,例如 AopTestUtils.getUltimateTargetObject(bean)

    我之前的解决方法是使用 Springs 的 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;
    }
    

    【讨论】:

    • 你能否用 Spring org.springframework.test.util.AopTestUtils class 更新你的答案。
    • 我目前不再使用 Java/Spring。您能否详细说明我应该如何更新我的答案?
    • Spring 团队基本上实现了与您相同的实用程序方法,因此您不必自己编写。简单的方法调用AopTestUtils.getUltimateTargetObject(bean) 将打开所有代理并返回初始对象。
    【解决方案2】:

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

    @InjectMock 标记应执行注入的字段。

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

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

    属性设置器注入; mocks 会先按类型解析,如果有多个相同类型的属性,则通过属性名和 mock 名的匹配来解析。

    注意 1:如果你有相同类型(或相同擦除)的属性,最好用匹配的属性命名所有 @Mock 注释字段,否则 Mockito 可能会混淆并且注入失败'不会发生。

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

    字段注入; mocks 会先按类型解析,如果有多个相同类型的属性,则通过字段名称和 mock 名称的匹配来解析。

    注意 1: 如果你有相同类型(或相同擦除)的字段,最好用匹配的字段命名所有 @Mock 注释的字段,否则 Mockito 可能会混淆并且注入失败'不会发生。

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

    【讨论】:

    • 这是个好主意,但我想在 spring bean 图中使用这个模拟进行更深入的集成测试。
    猜你喜欢
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    相关资源
    最近更新 更多