java - Spring AOP 何时使用 CGLIB 代理?

标签 java spring proxy spring-aop cglib

我正在阅读一些关于 Spring AOP 的文章并遇到了这个问题:

AOP proxy: the object created by AOP to implement the aspect contracts. In Spring, proxy objects can be JDK dynamic proxies or CGLIB proxies. By default, the proxy objects will be JDK dynamic proxies, and the object being proxied must implement an interface, that will also be implemented by the proxy object. But a library like CGLIB can be used to create proxies by subclassing too, so an interface is not needed.



你能看看下面的结构并想象我们想要建议bar()方法。
public interface Foo {
    void foo();
}

public class FooImpl implements Foo {

    @Override
    public void foo() {
        System.out.println("");
    }

    public void bar() {
        System.out.println("");
    }

}

这是否意味着在这种情况下将使用 CGLIB 代理?
由于 JDK 动态代理无法实现任何接口(interface)来覆盖 bar()方法。

最佳答案

如果你告诉它,Spring 只会使用 CGLIB。这通过设置 proxyTargetClass 启用(对于基于注释的配置) @EnableAspectJAutoProxy 的元素至true .

@EnableAspectJAutoProxy(proxyTargetClass = true)

考虑这个最小的例子(假设你的 FooImpl@Component 注释)
@Aspect
@Component
class FooAspect {
    @Before("execution(public void bar())")
    public void method() {
        System.out.println("before");
    }
}

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Example.class);
        FooImpl f = ctx.getBean(FooImpl.class); // throw exception here
        f.bar();
    }
}

默认情况下,proxyTargetClassfalse .在这种情况下,Spring 不会使用 CGLIB。因为 @Before @Aspect 中的建议类,Spring 将决定它需要代理 FooImpl使用 JDK 代理。不幸的是,由于这种代理行为,实际存储在上下文中的 bean 将是动态 JDK Proxy类型(也是 Foo 接口(interface)的子类型),因此尝试使用 FooImpl.class 获取 bean将失败。

即使您尝试将其检索为 Foo ,您将无法调用 bar()方法,因为代理对象不是 FooImpl .

如果启用 proxyTargetClass ,上面的代码按预期工作,创建了一个 CGLIB 代理,@Before建议被调用。

关于java - Spring AOP 何时使用 CGLIB 代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51795511/

相关文章:

java - java - 如何在java中以快速干净的方式中止线程?

java - Java List 的高效循环

java - 如何使用 iText 获取使用多种字体渲染的 pdf

java - bean ……它到底是什么

git - 如何绕过我使用 git config 设置的 http.proxy?

Node.js Express-Session 代理选项有什么作用?

java - Comparator.reversed() 不使用 lambda 进行编译

java - 将响应映射到 Java 中的类

java - 如何保证删除或更新成功而不需要额外请求?

javascript - 通过 promise 返回 ES6 代理时堆栈溢出