Spring AOP代理无法按预期工作

bay*_*mon 5 java proxy spring dependency-injection aspectj

实际上我对弹簧代理的行为感到困惑.我想我知道j2ee,cglib和aspectj的代理机制之间的主要区别.我在配置类中启用了aspectj自动代理,并且aspectj包含在类路径中.

我的配置

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ApplicationConfiguration {
    ...
}
Run Code Online (Sandbox Code Playgroud)

AspectJ依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.5</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

通过使用这个简单的设置,我假设bean注入按预期工作.但相反,我的应用程序会生成IllegalArgumentException带有"无法将[...]字段[...]设置为com.sun.proxy.$ Proxy30"的消息.这意味着Spring使用j2ee代理服务,即使启用了aspectj代理也是如此.

最后我发现我的服务上的接口导致了这种行为.当我的服务实现任何接口时,似乎spring决定使用j2ee代理.如果我删除它们,它的工作原理.

失败:

@Service
@Validated
public class MyService implements Interface1, Interface2 {

    @override
    public void methodFromInterface1() {
    }

    @override
    public void methodFromInterface2() {
    }

    public void serviceMethod() {
    }
}
Run Code Online (Sandbox Code Playgroud)

好:

@Service
@Validated
public class MyService {

    public void methodFromInterface1() {
    }

    public void methodFromInterface2() {
    }

    public void serviceMethod() {
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经明白j2ee代理需要接口.但对我来说这是新的,cglib/aspectj代理不适用于实现接口的bean.

有没有办法......

...强制春天不使用j2ee代理?

...强制spring使用cglib/aspectj代理(即使对于有接口的类)?

这是春天的错误或期望的行为吗?

编辑:更新示例,@Transational替换为@Validated

Edit2:解决方案: @Validated受到影响MethodValidationPostProcessor.因此proxyTargetClass必须true为此bean 设置属性.

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    final MethodValidationPostProcessor methodValidationPostProcessor;
    methodValidationPostProcessor = new MethodValidationPostProcessor();
    methodValidationPostProcessor.setProxyTargetClass(true);
    return methodValidationPostProcessor;
}
Run Code Online (Sandbox Code Playgroud)

Roh*_*ain 2

@EnableAspectJAutoProxy注释适用于@Aspect注释,而不适用于@Transactional注释。为此,您需要在类@EnableTransactionManagement上添加带有属性值的注释。@ConfigurationproxyTargetClass = true

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement(proxyTargetClass = true)
public class ApplicationConfiguration {
    ...
}
Run Code Online (Sandbox Code Playgroud)