2

我找不到任何理由说明为什么每个自动装配的 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 配置。什么可以关闭代理自动装配?

4

2 回答 2

6

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

于 2013-09-25T08:56:27.500 回答
5

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

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

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

于 2013-09-25T03:40:06.563 回答