[英]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.DelegatedScheduledExecutorService
在Executors
所在的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.