由事務註解引起的代理相關
阿新 • • 發佈:2019-02-25
void isa val 行修改 java動態代理 個性 織入 nsa tproxy
事務註解是通過spring aop代理實現
大致步驟是:
1、caller -》 aop 代理對象
2、aop代理對象的事務增強
3、代理interceptor 其他增強
4、執行目標對象的目標方法
5、按照4-》1 返回
代理:
aop代理 AopUtils.isAopProxy(bean)
cglib代理 AopUtils.isCglibProxy(bean)
java動態代理 AopUtils.isJdkDynamicProxy(bean)
問題:
public interface TestServiceImpl implements TestService{ @Transactional public void a(){ this.b(); } @Transactional public void b(){ } }
當a中調用b時,b的事務沒有執行,因為a調用b直接走步驟4,而不是通過aop代理的方式
解決方法:
調用方法改為:aopProxy.b();
1.通過ThreadLocal方法暴露Aop代理對象
<aop:aspectj-autoproxy expose-proxy="true"/>
2.this.b() ----> ((TestService)AopContext.currentProxy()).b();
其他方法:
1、將本身註入;或者 實現BeanPostProcessor 接口實現自身代理對象的註入;
註解:將本身註入的方式不適用於循環依賴的兩個對象,如果循環依賴,註入的可能不是代理對象,而是目標對象本身,達不到代理的目的;
AOP 相關
1、問題
針對同一類方法增加 同一類的日誌記錄、監控、安全監測等
2、解決方法
2.1 直接增加在方法裏;--- 重復,緊耦合
2.2 抽象類共性設計,子類個性化設計;--- 一榮俱榮一損俱損
2.3 裝飾器/代理模式設計;--- 緊耦合,每個實現類需要一個代理對象
2.4 動態代理(不適用於final類)
2.4.1 java動態代理---接口
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object retVal = null; boolean ok = true; // 代理方法之前的處理:條件判斷,日誌,權限等 if (!ok) { throw new RuntimeException("權限等"); } else { // 反射調用目標對象的方法 method.invoke(target, args); } // 此處可以是 目標對象方法之後的後處理 return retVal; }
2.4.2 cglib動態代理---接口和類
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object resVal = null;
/**
* 預處理
*/
boolean ok = true;
if (!ok) {
throw new RuntimeException("沒有權限");
} else {
resVal = methodProxy.invoke(target, objects);
}
/**
* 代理後處理
*/
return resVal;
}
動態代理本質:對目標對象增強;
代理限制:只能在父類方法調用之前或之後進行增強,不能在中間進行修改,想要在中間進行修改,需要ASM(java 字節碼生成庫);
2.5 Aop 代理
@Aspect
public class AopTest {
@Pointcut(value = "execution(* *(..))")
public void pointCut() {}
@Around(value = "pointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object retVal = null;
/**
* 前置處理...
*/
retVal = pjp.proceed();
/**
* 後置處理...
*/
return retVal;
}
}
AOP缺點:依賴aop框架;
3、aop 關註點.
關註點:所關註的任何東西;-- 需要被增強的各種方法;
關註點分離:將問題劃分為不可分割的單獨部分,單一獨立的模塊;
橫切點分離:會在多個模塊中出現,跨越多個模塊;一定要獨立,松耦合,可以隨意組合使用。
織入:橫切點分離之後,需要通過某種技術,將很切點融入到系統中,以完成需要的功能,因此需要織入。織入可能在編譯期、加載器或運行期等進行。
AOP 關註與業務無關,但是卻被各模塊公用的邏輯或功能,例如,日誌管理、權限控制、事務處理等,封裝起來,減少重復代碼,減少模塊之間的耦合度。
AOP代理(AOP Proxy):
AOP框架使用代理模式創建的對象,從而實現在連接點處插入增強(即應用切面),就是通過代理來對目標對象應用切面。在Spring中,AOP代理可以用JDK動態代理或CGLIB代理實現,而通過攔截器模型應用切面。默認使用jdk動態代理。
IOC/DI
- IOC (inversion of control)控制反轉
定義:控制權從應用轉移到框架(實現了IOC思想的容器成為IOC容器)
對象的創建過程:
1、創建對象
2、實例化(主動、被動)
3、依賴關系 (直接、間接)
4、裝配 (主動、被動)
創建可以由應用程序主動進行,完成1-4;也可以將2-4交由框架進行,使用的時候框架已經準備好了,可以直接使用;
對象創建的控制權轉移到了框架,這就是IOC。
==> 建立a對象,需要b屬性,則通過反射創建b對象,裝配到a對象中。
ps:容器提供組件運行環境 + 管理組件生命周期
IOC容器=容器+依賴裝配
- DI(Dependency Injection)依賴註入
用一個單獨的對象(裝配器IOC容器)來裝配對象之間的依賴關系。
註入方式:構造器註入、setter方式註入、接口註入等。
備註:IOC/DI 的開發思路
1、應用程序不主動創建對象,但需要描述創建他們的方式;
2、應用程序不直接進行服務的裝配,但需要配置文件描述組件和服務的依賴關系,容器會自動裝配他們。
原理:基於好萊塢原則--別來找我,我會去找你。也就是所有的組件都是被動的,組件的創建和裝配都有容器來管理。
由事務註解引起的代理相關