Spring AOP何时使用CGLIB代理?

时间:2018-08-11 00:45:48

标签: java spring proxy spring-aop cglib

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

  

AOP代理:由AOP创建以实现方面的对象   合同。在Spring中,代理对象可以是JDK动态代理,也可以是   CGLIB代理。默认情况下,代理对象将是动态的JDK   代理,并且要代理的对象必须实现一个接口,   也将由代理对象实现。但是像   CGLIB也可以通过子类化来创建代理,因此   不需要界面。

您能否看一下下面的结构,并想像一下我们想建议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动态代理无法实现任何接口来覆盖bar()方法。

3 个答案:

答案 0 :(得分:2)

Spring只会在您告知时使用CGLIB。通过将proxyTargetClass的{​​{1}}元素设置为@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(); } } proxyTargetClass。在这种情况下,Spring将不会使用CGLIB。由于false类中的@Before建议,Spring将决定需要使用JDK代理来代理@Aspect。不幸的是,由于这种代理行为,实际存储在上下文中的bean将具有动态JDK FooImpl类型(也是Proxy接口的子类型),因此尝试使用{{ 1}}将失败。

即使您尝试将其作为Foo进行检索,由于代理对象不是FooImpl.class,您也无法调用Foo方法。

如果启用bar(),则上面的代码将按预期工作,将创建CGLIB代理,并调用FooImpl建议。

答案 1 :(得分:0)

请参阅Spring文档中的AOP Proxies

  

Spring AOP默认将标准JDK动态代理用于AOP代理。这样可以代理任何接口(或一组接口)。

     

Spring AOP也可以使用CGLIB代理。这对于代理类而不是接口是必需的。默认情况下,如果业务对象未实现接口,则使用CGLIB。

答案 2 :(得分:-1)

Spring AOP默认将标准JDK动态代理用于AOP代理。这样可以代理任何接口(或一组接口)。

Spring AOP也可以使用CGLIB代理。这对于代理类而不是接口是必需的。如果业务对象未实现接口,则默认情况下使用CGLIB。因为对接口而不是类进行编程是一种好习惯;业务类通常将实现一个或多个业务接口。在那些需要建议在接口上未声明的方法,或者需要将代理对象作为具体类型传递给方法的情况下(在极少数情况下),可以强制使用CGLIB。 / p>

重要的是要掌握Spring AOP基于代理的事实。请参阅了解AOP代理以全面了解此实现细节的实际含义。

https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-introduction