簡體   English   中英

內的AspectJ(is(FinalType))丟失

[英]AspectJ within(is(FinalType)) missed

我正在使用AspectJ 1.8.10。 在我的代碼中,我有一個帶有ScheduledExecutorService的bean:

@Bean
public ScheduledExecutorService backgroundTaskExecutor() {
    return Executors.newSingleThreadScheduledExecutor();
}

實例化bean時,代理類拋出:

.AopConfigException: Could not generate CGLIB subclass of class [class java.util.concurrent.Executors$DelegatedScheduledExecutorService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class java.util.concurrent.Executors$DelegatedScheduledExecutorService

我知道,ScheduledExecutorService沒有構造函數是根本原因。 但是我需要配置方面的切入點以排除FinalType類。 像這樣:

@Before("!within(is(FinalType)) && execution(* your_method_name(..)) ")

但是,正如我提到的,aspectJ版本1.8.10無法識別is(..)語法。 (Intellij IDEA警告無法解析符號“是”)。 應用程序啟動時沒有AOP問題,但失敗了

java.lang.IllegalArgumentException: No visible constructors in class java.util.concurrent.Executors$DelegatedScheduledExecutorService

我做錯了什么? Aspectj> 1.8.4有什么變化嗎? (is(..)語法)

您已經配置了Spring AOP以強制創建CGLIB代理,甚至對於ScheduledExecutorService類的接口類型,也可以通過

@EnableAspectJAutoProxy(proxyTargetClass = true)

只需刪除proxyTargetClass = true部分或將其設置為false ,您的方面將起作用。 您不需要任何is(FinalType)切入點指示符,只需編寫類似

@Before("execution(* schedule*(..))")

為了攔截調度程序方法。


更新:讓我解釋一下為什么is(FinalType)對您沒有幫助,為什么認為它不起作用是錯誤的:

再次閱讀錯誤消息:

Could not generate CGLIB subclass of class
  [class java.util.concurrent.Executors$DelegatedScheduledExecutorService]:
  Common causes of this problem include using a final class or a non-visible class;
  nested exception is
    java.lang.IllegalArgumentException: No visible constructors in class
    java.util.concurrent.Executors$DelegatedScheduledExecutorService

“沒有可見的構造函數”並不意味着該類是最終的,它表示的是:只有沒有可見的構造函數。 實際上,內部靜態類Executors.DelegatedScheduledExecutorServiceExecutors所在的java.util.concurrent中受軟件包保護。 如果您查看源代碼,則會看到:

static class DelegatedScheduledExecutorService
        extends DelegatedExecutorService
        implements ScheduledExecutorService {

    private final ScheduledExecutorService e;

    DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
        super(executor);
        e = executor;
    }

    // (...)
}

看到? 這里沒有final堂課。 實際的問題是,由於JVM的限制,CGLIB不能創建子類:如果子類不是public ,則不能子類化另一個軟件包中的子類。

這就是為什么我告訴您讓Spring使用JDK動態代理並利用以下事實的事實:在這種情況下,不需要子類化,但是實現接口就足夠了。

暫無
暫無

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

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