实际上我对弹簧代理的行为感到困惑。我想我知道j2ee,cglib和aspectj的代理机制之间的主要区别。我在配置类中启用了aspectj自动代理,而aspectj包含在类路径中。
我的配置
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ApplicationConfiguration {
...
}
AspectJ依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
通过使用这种简单的设置,我假设豆注射按预期工作。但相反,我的应用程序会在IllegalArgumentException
s中生成类似&#34的消息;无法将[...]字段[...]设置为com.sun.proxy。$ Proxy30&#34;。这意味着Spring使用j2ee代理服务,即使启用了aspectj代理。
最后我发现我服务上的接口导致了这种行为。当我的服务实现任何接口时,似乎spring决定使用j2ee代理。如果我删除它们,它就可以工作。
失败:
@Service
@Validated
public class MyService implements Interface1, Interface2 {
@override
public void methodFromInterface1() {
}
@override
public void methodFromInterface2() {
}
public void serviceMethod() {
}
}
行:
@Service
@Validated
public class MyService {
public void methodFromInterface1() {
}
public void methodFromInterface2() {
}
public void serviceMethod() {
}
}
到目前为止,我已经明白j2ee代理需要接口。但它对我来说是新的,cglib / aspectj代理不能与实现接口的bean一起工作。
有办法......
...强迫spring不使用j2ee代理?
...强制spring使用cglib / aspectj代理(即使是有接口的类)?
这是春天的错误或期望的行为吗?
修改:更新了示例,@Transational
替换为@Validated
编辑2:解决方案: @Validated
受MethodValidationPostProcessor
影响。因此,此bean的属性proxyTargetClass
必须设置为true
。
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
final MethodValidationPostProcessor methodValidationPostProcessor;
methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setProxyTargetClass(true);
return methodValidationPostProcessor;
}
答案 0 :(得分:2)
@EnableAspectJAutoProxy
注释适用于@Aspect
注释,而不适用于@Transactional
注释。为此,您需要@Configuration
类@EnableTransactionManagement
注释,proxyTargetClass = true
属性值。
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement(proxyTargetClass = true)
public class ApplicationConfiguration {
...
}