日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

aop实现原理_SpringAOP原理分析

發(fā)布時間:2023/12/10 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 aop实现原理_SpringAOP原理分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

Spring核心知識

SpringAOP原理

AOP編程技術

什么是AOP編程

AOP底層實現(xiàn)原理

AOP編程使用

Spring核心知識

Spring是一個開源框架,Spring是于2003年興起的一個輕量級的Java開發(fā)框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來。它是為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的。框架的主要優(yōu)勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個組件,同時為J2EE應用程序開發(fā)提供集成的框架。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限于服務器端的開發(fā)。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。Spring的核心是控制反轉(IoC)和面向切面(AOP)。簡單來說,Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架。

為什么說Spring是一個一站式的輕量級開源框架呢?EE開發(fā)可分成三層架構,針對JavaEE的三層結構,每一層Spring都提供了不同的解決技術。

? WEB層:SpringMVC

? 業(yè)務層:Spring的IoC

? 持久層:Spring的JDBCTemplate(Spring的JDBC模板,ORM模板用于整合其他的持久層框架)

從上面的簡要介紹中,我們要知道Spring的核心有兩部分:

? IoC:控制反轉。

舉例來說,在之前的操作中,比方說有一個類,我們想要調用類里面的方法(不是靜態(tài)方法),就要創(chuàng)建類的對象,使用對象調用方法實現(xiàn)。對于Spring來說,Spring創(chuàng)建對象的過程,不是在代碼里面實現(xiàn)的,而是交給Spring來進行配置實現(xiàn)的。

AOP:面向切面編程。

SpringAOP原理

AOP編程技術

什么是AOP編程

AOP: Aspect Oriented Programming 面向切面編程。   面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個熱點。利用AOP可以對業(yè)務邏輯的各個部分進行隔離,從而使得業(yè)務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。 AOP是OOP的延續(xù),是(Aspect Oriented Programming)的縮寫,意思是面向切面(方面)編程。

主要的功能是:日志記錄,性能統(tǒng)計,安全控制,事務處理,異常處理等等。   

主要的意圖是:將日志記錄,性能統(tǒng)計,安全控制,事務處理,異常處理等代碼從業(yè)務邏輯代碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導業(yè)務邏輯的方法中,進而改 變這些行為的時候不影響業(yè)務邏輯的代碼。

可以通過預編譯方式和運行期動態(tài)代理實現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術。AOP實際是GoF設計模式的延續(xù),設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現(xiàn)。

假設把應用程序想成一個立體結構的話,OOP的利刃是縱向切入系統(tǒng),把系統(tǒng)劃分為很多個模塊(如:用戶模塊,文章模塊等等),而AOP的利刃是橫向切入系統(tǒng),提取各個模塊可能都要重復操作的部分(如:權限檢查,日志記錄等等)。由此可見,AOP是OOP的一個有效補充。

注意:AOP不是一種技術,實際上是編程思想。凡是符合AOP思想的技術,都可以看成是AOP的實現(xiàn)。

Aop, aspect object programming 面向切面編程

功能: 讓關注點代碼與業(yè)務代碼分離!

關注點

關注點,重復代碼就叫做關注點;

切面

關注點形成的類,就叫切面(類)!

面向切面編程,就是指 對很多功能都有的重復的代碼抽取,再在運行的時候網業(yè)務方法上動態(tài)植入“切面類代碼”。

切入點

執(zhí)行目標對象方法,動態(tài)植入切面代碼。

可以通過切入點表達式,指定攔截哪些類的哪些方法; 給指定的類在運行的時候植入切面類代碼。

AOP底層實現(xiàn)原理

代理設計模式

什么是代理模式

通過代理控制對象的訪問,可以詳細訪問某個對象的方法,在這個方法調用處理,或調用后處理。既(AOP微實現(xiàn)) ,AOP核心技術面向切面編程。

代理模式應用場景

SpringAOP、事物原理、日志打印、權限控制、遠程調用、安全代理 可以隱蔽真實角色

代理的分類

靜態(tài)代理(靜態(tài)定義代理類)

動態(tài)代理(動態(tài)生成代理類)

Jdk自帶動態(tài)代理

Cglib 、javaassist(字節(jié)碼操作庫)

靜態(tài)代理

什么是靜態(tài)代理

由程序員創(chuàng)建或工具生成代理類的源碼,再編譯代理類。所謂靜態(tài)也就是在程序運行前就已經存在代理類的字節(jié)碼文件,代理類和委托類的關系在運行前就確定了。

靜態(tài)代理代碼

public interface IUserDao { void save();}public class UserDao implements IUserDao { public void save() { System.out.println("已經保存數(shù)據..."); }}代理類public class UserDaoProxy implements IUserDao { private IUserDao target;? public UserDaoProxy(IUserDao iuserDao) { this.target = iuserDao; }? public void save() { System.out.println("開啟事物..."); target.save(); System.out.println("關閉事物..."); }?}

動態(tài)代理

什么是動態(tài)代理

1.代理對象,不需要實現(xiàn)接口

2.代理對象的生成,是利用JDK的API,動態(tài)的在內存中構建代理對象(需要我們指定創(chuàng)建代理對象/目標對象實現(xiàn)的接口的類型)

3.動態(tài)代理也叫做:JDK代理,接口代理

JDK動態(tài)代理

1)原理:是根據類加載器和接口創(chuàng)建代理類(此代理類是接口的實現(xiàn)類,所以必須使用接口 面向接口生成代理,位于java.lang.reflect包下)

2)實現(xiàn)方式:

通過實現(xiàn)InvocationHandler接口創(chuàng)建自己的調用處理器 IvocationHandler handler = new InvocationHandlerImpl(…);

通過為Proxy類指定ClassLoader對象和一組interface創(chuàng)建動態(tài)代理類Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});

通過反射機制獲取動態(tài)代理類的構造函數(shù),其參數(shù)類型是調用處理器接口類型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

通過構造函數(shù)創(chuàng)建代理類實例,此時需將調用處理器對象作為參數(shù)被傳入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

缺點:jdk動態(tài)代理,必須是面向接口,目標業(yè)務類必須實現(xiàn)接口

// 每次生成動態(tài)代理類對象時,實現(xiàn)了InvocationHandler接口的調用處理器對象 public class InvocationHandlerImpl implements InvocationHandler { private Object target;// 這其實業(yè)務實現(xiàn)類對象,用來調用具體的業(yè)務方法 // 通過構造函數(shù)傳入目標對象 public InvocationHandlerImpl(Object target) { this.target = target; }? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("調用開始處理"); result = method.invoke(target, args); System.out.println("調用結束處理"); return result; }? public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 被代理對象 IUserDao userDao = new UserDao(); InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao); ClassLoader loader = userDao.getClass().getClassLoader(); Class>[] interfaces = userDao.getClass().getInterfaces(); // 主要裝載器、一組接口及調用處理動態(tài)代理實例 IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl); newProxyInstance.save(); }}

CGLIB動態(tài)代理

原理:利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節(jié)碼生成子類來處理。

什么是CGLIB動態(tài)代理

使用cglib[Code Generation Library]實現(xiàn)動態(tài)代理,并不要求委托類必須實現(xiàn)接口,底層采用asm字節(jié)碼生成框架生成代理類的字節(jié)碼

CGLIB動態(tài)代理相關代碼

public class CglibProxy implements MethodInterceptor { private Object targetObject; // 這里的目標類型為Object,則可以接受任意一種參數(shù)作為被代理類,實現(xiàn)了動態(tài)代理 public Object getInstance(Object target) { // 設置需要創(chuàng)建子類的類 this.targetObject = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); }? public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("開啟事物"); Object result = proxy.invoke(targetObject, args); System.out.println("關閉事物"); // 返回代理對象 return result; } public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao()); userDao.save(); }}

CGLIB動態(tài)代理與JDK動態(tài)區(qū)別

java動態(tài)代理是利用反射機制生成一個實現(xiàn)代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。

而cglib動態(tài)代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節(jié)碼生成子類來處理。

Spring中。

1、如果目標對象實現(xiàn)了接口,默認情況下會采用JDK的動態(tài)代理實現(xiàn)AOP

2、如果目標對象實現(xiàn)了接口,可以強制使用CGLIB實現(xiàn)AOP

3、如果目標對象沒有實現(xiàn)了接口,必須采用CGLIB庫,spring會自動在JDK動態(tài)代理和CGLIB之間轉換

JDK動態(tài)代理只能對實現(xiàn)了接口的類生成代理,而不能針對類 。 CGLIB是針對類實現(xiàn)代理,主要是對指定的類生成一個子類,覆蓋其中的方法 。 因為是繼承,所以該類或方法最好不要聲明成final ,final可以阻止繼承和多態(tài)。

AOP編程使用

注解版本實現(xiàn)AOP

@Aspect 指定一個類為切面類 @Pointcut("execution(* com.service.UserService.add(..))") 指定切入點表達式@Before("pointCut_()") 前置通知: 目標方法之前執(zhí)行@After("pointCut_()") 后置通知:目標方法之后執(zhí)行(始終執(zhí)行)@AfterReturning("pointCut_()") 返回后通知: 執(zhí)行方法結束前執(zhí)行(異常不執(zhí)行)@AfterThrowing("pointCut_()") 異常通知: 出現(xiàn)異常時候執(zhí)行@Around("pointCut_()") 環(huán)繞通知: 環(huán)繞目標方法執(zhí)行??@Component@Aspectpublic class AopLog {? // 前置通知 @Before("execution(* com.service.UserService.add(..))") public void begin() { System.out.println("前置通知"); }?? // 后置通知 @After("execution(* com.service.UserService.add(..))") public void commit() { System.out.println("后置通知"); }? // 運行通知 @AfterReturning("execution(* com.service.UserService.add(..))") public void returning() { System.out.println("運行通知"); }? // 異常通知 @AfterThrowing("execution(* com.service.UserService.add(..))") public void afterThrowing() { System.out.println("異常通知"); }? // 環(huán)繞通知 @Around("execution(* com.service.UserService.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("環(huán)繞通知開始"); proceedingJoinPoint.proceed(); System.out.println("環(huán)繞通知結束"); }}

XML方式實現(xiàn)AOP

Xml實現(xiàn)aop編程:

1) 引入jar文件 【aop 相關jar, 4個】
2) 引入aop名稱空間
3)aop 配置
* 配置切面類 (重復執(zhí)行代碼形成的類)
* aop配置
攔截哪些方法 / 攔截到方法后應用通知代碼

? ? ?public class AopLog2 {? // 前置通知 public void begin() { System.out.println("前置通知"); }? // // 后置通知 public void commit() { System.out.println("后置通知"); }? // 運行通知 public void returning() { System.out.println("運行通知"); }? // 異常通知 public void afterThrowing() { System.out.println("異常通知"); }? // 環(huán)繞通知 public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("環(huán)繞通知開始"); proceedingJoinPoint.proceed(); System.out.println("環(huán)繞通知結束"); }}

JAVA進階架構程序員福利:我這里還總結整理了比較全面的JAVA相關的面試資料,都已經整理成了

PDF版,這些都可以分享給大家,關注私信我:【806】,免費領取

總結

以上是生活随笔為你收集整理的aop实现原理_SpringAOP原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。