簡體   English   中英

Spring AOP 什么時候使用 CGLIB 代理?

[英]When is CGLIB proxy used by Spring AOP?

我正在閱讀一些關於 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()方法。

如果你告訴它,Spring 只會使用 CGLIB。 這是通過設定使能(對於基於注釋配置) proxyTargetClass的元件@EnableAspectJAutoProxytrue

@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。 由於@Aspect類中的@Before建議,Spring 將決定它需要使用JDK 代理來代理FooImpl 不幸的是,由於這種代理行為,實際存儲在上下文中的 bean 將是動態 JDK Proxy類型(也是Foo接口的子類型),因此嘗試使用FooImpl.class獲取 bean 將失敗。

即使您嘗試將其作為Foo檢索,您也無法調用bar()方法,因為代理對象不是FooImpl

如果啟用proxyTargetClass ,上面的代碼將按預期工作,創建 CGLIB 代理,並調用@Before建議。

請參閱 Spring 文檔中的AOP 代理

Spring AOP 默認為 AOP 代理使用標准的 JDK 動態代理。 這允許代理任何接口(或接口集)。

Spring AOP 也可以使用 CGLIB 代理。 這是代理類而不是接口所必需的。 默認情況下,如果業務對象未實現接口,則使用 CGLIB。

Spring AOP 默認為 AOP 代理使用標准的 JDK 動態代理。 這允許代理任何接口(或接口集)。

Spring AOP 也可以使用 CGLIB 代理。 這是代理類而不是接口所必需的。 如果業務對象未實現接口,則默認使用 CGLIB。 因為編程接口而不是類是一種很好的做法; 業務類通常會實現一個或多個業務接口。 在需要建議未在接口上聲明的方法或需要將代理對象作為具體類型傳遞給方法的情況下(希望很少見),可以強制使用 CGLIB。

掌握 Spring AOP 是基於代理的這一事實很重要。 請參閱了解 AOP 代理以徹底檢查此實現細節的實際含義。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM