【问题标题】:Why proxy is not used to autowire为什么代理不用于自动装配
【发布时间】:2013-09-25 02:39:22
【问题描述】:

我找不到任何理由说明为什么每个自动装配的 bean 都不是由代理自动装配的。我知道因为 @Transactional 注释不起作用,我在 Eclipse 中调试期间检查了自动装配组件。当然,每个组件都实现了一些接口,我使用与接口相关的@Autowired 注释。 我只有一个aop的配置:

<tx:annotation-driven transaction-manager="transactionManager" />

我将 JPA 与 hibernate、spring-mvc、spring-webflow、spring-security 和 spring-data 一起使用。扩展org.springframework.data.repository.CrudRepository 的接口由代理自动连接。但我的组件不是。例如我有类MyClass,它实现了MyInterface

@Service
public class MyClass implements MyInterface {
@Autowired
MyCrudReposiotry reposiotry;
....
}

如果我在某处自动装配 MyInterface:

@Autowired
MyInterface mi;

那么mi 只是对MyClass 对象的引用,存储库是对代理org.springframework.aop.framework.JdkDynamicAopProxy 的引用。非常有趣的是,在测试中mi 是对代理的引用。我的测试上下文不包含 web-flow 和 mvc 配置。

也许我应该检查一些间接的 aop 配置。什么可以关闭代理自动装配?

【问题讨论】:

    标签: spring proxy-classes


    【解决方案1】:

    我的猜测是您正在扫描相同的组件两次。您的根上下文中可能有一个(用于 ContextLoaderListener)和一个用于 DispatcherServlet。否,如果两者都扫描相同的类,您最终会重复(以及一个代理实例和一个非代理实例)。

    【讨论】:

    • 非常感谢您的帮助。你是对的,问题是&lt;context:component-scan .. /&gt;。我只有一个&lt;context:component-scan .. /&gt;,但只在 DispatcherServlet 上下文中。现在我有一个&lt;context:component-scan .. /&gt; 用于DispatcherServlet 上下文中的控制器包,第二个&lt;context:component-scan .. /&gt; 用于根上下文中的服务包,它可以工作。
    【解决方案2】:

    代理和自动连接是相互独立的。当您使用@AutoWired 时,它会找到另一个实现所需接口的bean 并将其注入。它找到的 bean 实例可能是普通对象或代理 - 这与 Autowired 无关。

    spring 会自动为某些 bean 创建代理。正如您所注意到的,当您使用@Transactional 时会发生这种情况。当 spring 容器实例化具有 @Transactional 注释的 bean 时,该对象被包装在代理中。实际对象被上下文中的代理替换。这样做是为了让 spring 可以拦截对这些方法的调用,并在方法调用之前和之后添加开始/提交事务调用。这是由 spring-aop 模块实现的。任何依赖 AOP(@Transactional@Secured)的功能都会导致创建代理。

    使用代理的另一种情况是动态创建实现。在 CRUDRepository 的情况下,您只需要实现接口。它的实现是使用相同的代理基础架构动态创建的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-19
      • 2013-09-28
      • 2012-04-23
      • 2015-11-14
      • 1970-01-01
      • 2012-07-14
      • 2018-04-16
      • 2015-12-02
      相关资源
      最近更新 更多