[英]Spring JDK Dynamic Proxy and CGLIB - implementation details
我的問題與“代理內部的自我調用問題”有關,但這不是我的問題。 (我已經找到了解決該問題的一些方法,例如,如此處所述 )。 我還發現基本解釋為什么出現這種情況, 在這里
從一開始就開始,我第一次遇到了“自我調用”的問題。 我們正在使用Spring Boot,我們有一些服務需要審計一些數據(使用AspectJ),以及PreAuthorize該方法。 該方法本身必須返回一些內容,但審核其他內容。 所以現在我們的服務看起來像:
class Service {
Service self;
public Service() {
// I don't like this because it makes my Service to be aware of the fact that it's a proxy. I just wanted my class to be a pojo with annotations
self = AopContext.currentProxy();
}
@Audit
public CustomClassContainingTheValuesToAudit getValuesFromServer() {
CustomClassContainingTheValuesToAudit c;
try {
Object answer = self.doGetValuesFromServer();
c = ... ; // create what to audit based on the answer
} catch (...) {
// log the fact that you didn't have enough privileges to run doGetValuesFromServer()
// create c based on the exception I got
c = ...;
}
return c; // object to be audited
}
@PreAuthorize(.....)
public Object doGetValuesFromServer() {
.........
}
}
我主要關心的是如上所述讓AspectJ + PreAuthorize協同工作,但沒有讓我的班級意識到它被代理的事實。 所以我想確切地了解我在代理類型方面的選擇是什么。 我發現Spring帶有兩種代理:JDK Dynamic Proxies和CGLIB代理。 原來我們正在使用CGLIB代理,我們將Spring配置為使用CGLIB(無論如何,現在Service只是一個普通類,沒有實現接口)。 幾個小時后,我閱讀了關於AOP +的Spring文檔以及我在互聯網上找到的任何其他內容,以便了解我的類在代理后的樣子。 我認為實現我想要的唯一選擇是使用代理的其他(第三個?)實現
1)根據我對代碼現在的樣子的描述,你會做些什么來避免從上下文中取出bean? 我不想打破兩個類中的每個服務,以避免自我調用問題。 我想要一種方法來使aspectJ和PreAuthorize按照描述工作。 2)我不明白為什么CGLIB以它的方式實現代理。 所以,假設我有班級服務
class Service {
public void methodA(){
// do methodA stuff
// call method b
methodB();
}
public void methodB(){
// do methodB stuff
}
}
然后GCLIB將生成一個類,如:
class Service$CGLIB extends Service {
// it's only extending my class to make it compatible with the variable where i'm storing/autowiring the proxy
Service privateField; // but it's actually using a decorator pattern, just like JDK Dynamic Proxies do
public void methodA() {
// do any magic before
privateField.a();
// any magic after the call
}
public void methodB() {
// magic
privateField.b();
// some more magic
}
}
為什么CGLIB只調用super.a()和super.b()? 為什么需要裝飾而不是委托呢? 我認為我需要的是代理委托給super。 我是這樣做的,因為多態性,我對自我調用沒有任何問題。 是否有代理的實現可以完成我期望CGLIB做的事情?
Cglib-proxies的行為與cglib如何工作的方式無關,但與Spring如何使用cglib無關。 Cglib能夠委派或子類化調用。 看看實現這個委托的Spring的DynamicAdvisedInterceptor
。 使用MethodProxy
,它可以改為執行超級方法調用。
Spring定義委托而不是子類,以便最小化使用Cglib或Java代理之間的差異。 這只是一個選擇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.