【发布时间】:2015-05-19 02:34:35
【问题描述】:
实际上,我对 spring 代理的行为感到困惑。我想我知道 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>
通过使用这个简单的设置,我假设 bean 注入按预期工作。但相反,我的应用程序导致 IllegalArgumentExceptions 出现“无法将 [...] 字段 [...] 设置为 com.sun.proxy.$Proxy30”之类的消息。这意味着即使启用了 aspectj 代理,spring 也会为我的服务使用 j2ee 代理。
最后我发现我的服务上的接口导致了这种行为。当我的服务实现任何接口时,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
Edit2:解决方案:@Validated 受MethodValidationPostProcessor 影响。所以这个 bean 的属性 proxyTargetClass 必须设置为 true。
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
final MethodValidationPostProcessor methodValidationPostProcessor;
methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setProxyTargetClass(true);
return methodValidationPostProcessor;
}
【问题讨论】:
标签: java spring dependency-injection proxy aspectj