Spring AOP的底層實現原理
Spring的兩大核心之一就是AOP,AOP:面向切面程式設計。在說原理之前,得先知道一些AOP的專業術語。
AOP的專業術語
連線點(JoinPoint):增強執行的位置(增加程式碼的位置),Spring只支援方法;
切點(PointCut):具體的連線點;一般可能通過一個表示式來描述;
增強(Advice):也稱為訊息,指的是增加的額外的程式碼,Spring中,增強除了包含程式碼外,還包含位置資訊;
Spring中一共有四種增強:
MethodBeforeAdvice:前置增強
MethodInterceptor:環繞增強
ThrowsAdvice:異常增強
AfterReturingAdvice
引介(Introduction):特殊的增強,動態為類增加方法
織入(Weaving):將增強加入到目標類的過程,織入分為三種時期
編譯器:AspectJ
類載入
執行期:jdk動態代理(實現介面),CGlib(子類,不能用final)
目標物件(Target):原始物件
代理物件(Proxy):加入了增強的物件,是生成的;
切面(Aspect):切點+增強
接下來我要說的就是在執行期間織入的兩種實現方式
JDK動態代理(實現介面)
什麼是代理模式呢?
代理模式有三個角色,分別是
抽象角色:介面
目標角色:實現類
代理角色:實現介面(InvocationHandler),並引用目標角色
代理模式與裝飾者模式的區別
類圖(結構)基本一樣,但目的不同,裝飾模式的前提是已經所有的類,並進行組裝;而
使用代理模式時,我們不能直接訪問目標角色或沒有許可權訪問時,可以使用代理模式
代理模式分為兩種
靜態代理:需要為每個目標角色,建立一個對應的代理角色;類的數量會急劇膨脹
動態代理:自動為每個目標角色生成對應的代理角色
接下來就是jdk動態代理的程式碼:
實現jdk動態代理的前提是所有的目標類都必須要基於一個統一的介面
建立統一的介面
package com.dao; /** * 為目標類定義統一的介面SleepDao * @author XuXQ * */ public interface SleepDao { public void sleep(); }
定義目標物件
package com.daoImpl;
import com.dao.SleepDao;
/**
* 目標類
* @author XuXQ
*
*/
public class SleepDaoImpl implements SleepDao {
@Override
public void sleep() {
System.out.println("本大人要睡覺了");
}
}
建立代理角色
package com.handler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 建立的類得需要實現InvocationHandler,並重寫invoke()方法
* InvocationHandler 是代理例項的呼叫處理程式 實現的介面
* 即:MyInvocationHandler 是代理例項的呼叫處理程式
* @author XuXQ
*
*/
public class MyInvoctionHandler implements InvocationHandler {
Object object=null;//目標物件
public MyInvoctionHandler(Object object) {
super();
this.object = object;
}
/**
* proxy=代理物件
* method=被呼叫方法的方法名
* args=被呼叫方法的引數
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("睡覺前要脫衣服啊");
Object obj=method.invoke(object, args);//obj為目標物件呼叫方法的返回值
System.out.println("睡著了當然得做個美夢啊");
return obj;
}
}
編寫測試用例
package com.handler;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.dao.SleepDao;
import com.daoImpl.SleepDaoImpl;
public class Test1 {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void test() {
//目標類必須基於統一的介面
SleepDao s=new SleepDaoImpl();
ClassLoader classLoader=s.getClass().getClassLoader();
MyInvoctionHandler myInvoctionHandler=new MyInvoctionHandler(s);
//Proxy為InvocationHandler實現類動態建立一個符合某一介面的代理例項
SleepDao sd=(SleepDao) Proxy.newProxyInstance(classLoader, s.getClass().getInterfaces(), myInvoctionHandler);
//相當於呼叫代理角色的Invoke()
sd.sleep();
}
}
結果:
由結果可以看到成功的將增強織入到了目標物件中了
CGlib代理
package com.cglibproxy;
/**
* 和JDK動態代理不同,不需要建立統一的介面
* @author XuXQ
*
*/
public class Base {
public void sleep(){
System.out.println("本大少要睡覺啦");
}
}
建立cglib的代理物件
package com.cglibproxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
//用來生成代理物件
public class CglibProxy implements MethodInterceptor {
public Object getProxy(Object object){
Enhancer e=new Enhancer();//建立代理物件類
e.setSuperclass(object.getClass());//宣告代理物件的父類是誰(是目標物件)
e.setCallback(this);//設定回撥函式,即呼叫intercept()
return e.create();//返回建立的代理物件
}
/**
* proxy=代理物件,也是目標物件的子類
* args=方法引數
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable {
System.out.println("你個大懶豬,竟然睡覺前不脫衣服,嫌棄o");
Object object=arg3.invokeSuper(proxy, args);
System.out.println("起床啦,要不然得遲到了哦");
return null;
}
}
編寫測試用例
package com.cglibproxy;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
public class Test {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@org.junit.Test
public void test() {
CglibProxy proxy=new CglibProxy();
Base base=(Base) proxy.getProxy(new Base());
base.sleep();
}
}
結果:
由結果同樣可以看到成功的將增強織入到了目標物件中了
總結
當然我們以後寫程式碼都是基於Aspect,直接寫註解的,當然這並不代表這我們不需要知道AOP
底層的實現原理,至於註解用的是哪種實現方式,使用配置來解決的,這裡就不詳解了。
相關推薦
Spring AOP底層實現原理
1、spring的AOP底層是由 JDK提供的動態代理技術 和 CGLIB(動態位元組碼增強技術)實現。 2、JDK動態代理:Jdk動態代理只針對於介面操作。 3、CGLIB:可以針
Spring技術內幕:Spring AOP的實現原理(三)
dede ide configure ida mini == src min dem 生成SingleTon代理對象在getSingleTonInstance方法中完畢,這種方法時ProxyFactoryBean生成AopProxy對象的入口。代理對象會
AOP底層實現原理,動態代理如何動態
需求 原理 靜態代理 朋友 hand 自己 依賴 開發 ava 代理 指定另外一個主體代替原來的某個主體去執行某個事物 代理執行的人 需要代理的人 需要代理的事情是一定要做的 但是被代理的人沒有時間或自己做的不專業 靜態代理: 父母朋友幫忙物色找對象 代理人掌握需求,專
Spring AOP 的實現原理
class文件 ndb 是我 反射 ofo 直接 pri 關註 選擇 AOP(Aspect Orient Programming),我們一般稱為面向方面(切面)編程,作為面向對象的一種補充,用於處理系統中分布於各個模塊的橫切關註點,比如事務管理、日誌、緩存等等。AOP實現的
Spring AOP的實現原理
代碼生成 time .get hand 日誌 aop 分布 class a cee AOP(Aspect Orient Programming),我們一般稱為面向方面(切面)編程,作為面向對象的一種補充,用於處理系統中分布於各個模塊的橫切關註點,比如事務管理、日誌、緩存等等
【spring】Spring aop的實現原理
本文轉載自https://www.cnblogs.com/lcngu/p/5339555.html。 Spring aop的實現原理 簡介 前段時間寫的java設計模式--代理模式,最近在看Spring Aop的時候,覺得於代理模式應該有密切的聯絡,於是決定了解下Sprin
深入理解spring事務底層實現原理
事務 相信大家都在ATM機取過錢,但是是否有人考慮過它的流程是怎樣的呢? 我們都知道,假如我們取300塊錢,那麼當這三百塊錢從ATM機出來時,我們的賬戶相應的會減少300。這兩個過程一定是要同時成功才算成功的。否則就會出現賬戶少了300.但是錢沒出來,對於我們來
反射實現 AOP 動態代理模式例項說明(Spring AOP 的實現 原理)
說明以下,spring aop的實現原理不是用java的動態代理。是用代理模式和CGLib (Code GenerationLibrary), 不過現在不用CGLib(Code Generation Library),直接用ASM框架來操作位元組碼了。 好長時間沒有用過S
Spring Aop 原始碼實現原理分析
更新:2018/4/2 修改字型、新增引言。0 引言AOP是Aspect Oriented Programing的簡稱,面向切面程式設計。AOP適合於那些具有橫切邏輯的應用:如效能監測,訪問控制,事務管理、快取、物件池管理以及日誌記錄。AOP將這些分散在各個業務邏輯中的程
Spring AOP IOC 實現原理,面試問到如何回答
IOC:控制反轉也叫依賴注入,IOC利用java反射機制,AOP利用代理模式。所謂控制反轉是指,本來被呼叫者的例項是有呼叫者來建立的,這樣的缺點是耦合性太強,IOC則是統一交給spring來管理建立,將物件交給容器管理,你只需要在spring配置檔案總配置相應的
Spring AOP底層實現- JDK動態代理和CGLIB動態代理
Spring AOP是執行時織入的,那麼執行時織入到底是怎麼實現的呢?答案就是代理物件。 代理又可以分為靜態代理和動態代理。 靜態代理:由程式設計師建立或特定工具自動生成原始碼,再對其編譯。在程式執行前,代理類的.class檔案就已經存在了。
Spring AOP的實現原理—— 靜態代理和動態代理
AOP(Aspect Orient Programming),我們一般稱為面向方面(切面)程式設計,作為面向物件的一種補充,用於處理系統中分佈於各個模組的橫切關注點,比如事務管理、日誌、快取等等。 AOP實現的關鍵在於AOP框架自動建立的AOP代理,
Spring IOC和Spring AOP的實現原理(原始碼主線流程)
寫在前面 正本文參考了《spring技術內幕》和spring 4.0.5原始碼。本文只描述原理流程的主線部分,其他比如驗證,快取什麼可以具體參考原始碼理解。Spring IOC一、容器初始化 容器的初始化首先是在對應的構造器中進行,在application
Spring AOP的實現原理(二)
**二、AOP的設計與實現 1、JVM的動態代理特性** 在Spring AOP實現中, 使用的核心技術時動態代理,而這種動態代理實際上是JDK的一個特性。通過JDK的動態代理特性,可以為任意Java物件建立代理物件,對於具體使用來說,這個特性使通過Java Reflectio
反射實現 AOP 動態代理模式(Spring AOP 的實現 原理)
{40 //反射得到操作者的例項41 Class clazz = this.proxy.getClass();42 //反射得到操作者的Start方法43 Method start = clazz.getDeclaredM
Spring Aop底層原理詳解(利用spring後置處理器實現AOP)
寫在前面:對於一個java程式設計師來說,相信絕大多數都有這樣的面試經歷,面試官問:你知道什麼是aop嗎?談談你是怎麼理解aop的?等等諸如此類關於aop的問題。當然對於一些小白可能會一臉懵逼;對於一些工作一兩年的,可能知道,哦!aop就是面向切面變成,列印日誌啊,什麼什麼的,要是有點學
探析Spring AOP(三):Spring AOP的底層實現原理
一、前言 前面第一篇我們講到了AOP的概念和使用,第二篇也講到了 AOP的實現機制,在第一篇,講到了joinpoint,pointcut,aspect,weave等AOP的核心概念,接下來我們詳解分析他們的實現原理! 在動態代理 和 CGLIB 的支
Spring AOP的底層實現原理
Spring的兩大核心之一就是AOP,AOP:面向切面程式設計。在說原理之前,得先知道一些AOP的專業術語。 AOP的專業術語 連線點(JoinPoint):增強執行的位置(增加程式碼的位置),Spring只支援方法; 切點(PointCut):具體的連線點;一般可能通過
菜鳥學SSH——Spring容器AOP的實現原理——動態代理
之前寫了一篇關於IOC的部落格——《Spring容器IOC解析及簡單實現》,今天再來聊聊AOP。大家都知道Spring的兩大特性是IOC和AOP。 IOC負責將物件動態的注入到容器,從而達到一種需要誰就注入誰,什麼時候需要就什麼時候注入的效果,可謂是招之則來,揮之則去。想想都覺得爽,如果現實
【Spring】:aop的實現原理
銜接前篇文章:https://blog.csdn.net/hxcaifly/article/details/85061330 前言 前段時間寫的java設計模式–代理模式,最近在看Spring Aop的時候,覺得於代理模式應該有密切的聯絡,於是決定了解下Spring A