我找不到为什么每个自动装配的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配置。什么可以通过代理关闭自动装配?
答案 0 :(得分:6)
我的猜测是你要扫描两次相同的组件。您可能在根上下文中(对于ContextLoaderListener)和一个用于DispatcherServlet。如果两者扫描相同的类,则最后是重复的(以及一个代理和一个非代理实例)。
答案 1 :(得分:4)
代理和自动布线彼此独立。当您使用@AutoWired
时,它会找到另一个实现所需接口并注入它的bean。它找到的bean实例可能是普通对象或代理 - 它与Autowired无关。
弹簧会自动为某些bean创建代理。正如您已经注意到,当您使用@Transactional
时会出现这种情况。当spring容器实例化具有@Transactional
注释的bean时,对象将被包装在代理中。实际对象在上下文中由代理替换。这样做是为了使spring能够拦截对这些方法的调用,并在方法调用之前和之后添加begin / commit事务调用。这是由spring-aop模块实现的。任何依赖AOP(@Transactional
,@Secured
)的功能都将导致代理的创建。
使用代理的另一种情况是动态创建实现。如果是CRUDRepository,则只需要实现该接口。使用相同的代理基础架构即时创建它的实现。