spring aop原理:1、AOP 面向切面,是一種程式設(shè)計(jì)範(fàn)式,提供從另一個(gè)角度來考慮程式結(jié)構(gòu)以完善物件導(dǎo)向程式設(shè)計(jì)OOP;2、AOP為開發(fā)者提供了一種描述橫切關(guān)注點(diǎn)的機(jī)制,並且能夠自動(dòng)將橫切關(guān)注點(diǎn)織入到物件導(dǎo)向的軟體系統(tǒng)中。
spring aop原理:
AOP(面向切面)是一種程式設(shè)計(jì)範(fàn)式,提供從另一個(gè)角度來考慮程式結(jié)構(gòu)以完善物件導(dǎo)向程式設(shè)計(jì)(OOP)。
AOP為開發(fā)者提供了一種描述橫切關(guān)注點(diǎn)的機(jī)制,並能夠自動(dòng)將橫切關(guān)注點(diǎn)織入到物件導(dǎo)向的軟體系統(tǒng)中,從而實(shí)現(xiàn)了橫切關(guān)注點(diǎn)的模組化。
AOP能夠?qū)⒛切┡c業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模組所共同調(diào)用的邏輯或責(zé)任,例如事務(wù)處理、日誌管理、權(quán)限控制等,封裝起來,便於減少系統(tǒng)的重複程式碼,降低模組間的耦合度,並有利於未來的可操作性和可維護(hù)性。
使用AOP的好處
降低模組的耦合度
讓系統(tǒng)容易擴(kuò)充
#提高程式碼復(fù)用性
AOP的基本概念
連接點(diǎn)(JoinPoint):需要在程式中插入橫切關(guān)注點(diǎn)的點(diǎn),連接點(diǎn)可能是在類別初始化、方法呼叫、欄位呼叫或處理異常等等。 Spring中只支援方法執(zhí)行連接點(diǎn)。
切入點(diǎn)(Pointcut):一組相關(guān)連接點(diǎn)的集合。
通知(Advice):在連接點(diǎn)上執(zhí)行的行為,增強(qiáng)提供了在AOP中需要在切入點(diǎn)所選擇的連接點(diǎn)處擴(kuò)展現(xiàn)有行為的手段。包括前置增強(qiáng)(before advice)、後置增強(qiáng) (after advice)、環(huán)繞增強(qiáng) (around advice)。
切面(Aspect):通知與切入點(diǎn)的結(jié)合。
織入(Weaving):織入是一個(gè)過程,是將切面應(yīng)用到目標(biāo)物件從而創(chuàng)建出AOP代理物件的過程。
代理程式(Proxy):透過代理方式來對(duì)目標(biāo)物件套用切面。 AOP代理可以用JDK動(dòng)態(tài)代理或CGLIB代理實(shí)現(xiàn)。
目標(biāo)物件(Target):需要被織入關(guān)注點(diǎn)的物件。即被代理的對(duì)象。
實(shí)作AOP的主要設(shè)計(jì)模式就是動(dòng)態(tài)代理。
Spring的動(dòng)態(tài)代理有兩種:一是JDK的動(dòng)態(tài)代理;另一個(gè)是cglib動(dòng)態(tài)代理。
JDK動(dòng)態(tài)代理程式模擬
JDK動(dòng)態(tài)代理程式的兩個(gè)核心介面(類別)分別是InvocationHandler和Proxy。注意:只能代理介面。
public class TimeHandler implements InvocationHandler { // 目標(biāo)對(duì)象 private Object targetObject; public TimeHandler(Object targetObject){ this.targetObject = targetObject; } @Override //關(guān)聯(lián)的這個(gè)實(shí)現(xiàn)類的方法被調(diào)用時(shí)將被執(zhí)行 /*InvocationHandler接口的方法,proxy表示代理,method表示原對(duì)象被調(diào)用的方法, args表示方法的參數(shù)*/ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret=null; try{ System.out.println("方法之前:"+System.currentTimeMillis()); //調(diào)用目標(biāo)方法 ret=method.invoke(targetObject, args); System.out.println("方法之后:"+System.currentTimeMillis()); }catch(Exception e){ e.printStackTrace(); System.out.println("error"); throw e; } return ret; } }
TimeHandler 類別實(shí)作了InvocationHandler介面。實(shí)作核心方法invoke,共有3個(gè)參數(shù)。第一個(gè)參數(shù) 產(chǎn)生的代理類別實(shí)例,第二個(gè)參數(shù) 目標(biāo)物件的方法,第三個(gè)參數(shù) 方法的參數(shù)值陣列。
public class ProxyUtil { @SuppressWarnings("unchecked") public static <T> T proxyOne(ClassLoader loader,Class<?>[] clz,InvocationHandler handler){ return (T)Proxy.newProxyInstance(loader, clz, handler); } }
ProxyUtil 類別簡(jiǎn)單封裝了一下Proxy.newProxyInstance()方法。此方法也有3個(gè)參數(shù)。第一個(gè)參數(shù)產(chǎn)生代理物件的類別載入器,第二個(gè)參數(shù)目標(biāo)物件的介面數(shù)組,第三個(gè)參數(shù)就是實(shí)作InvocationHandler介面的類別實(shí)例。
public interface UserManager { public void addUser(String userId, String userName); } public class UserManagerImpl implements UserManager { @Override public void addUser(String userId, String userName) { System.out.println("addUser(id:"+userId+",name:"+userName+")"); } } public static void main(String[] args) { UserManager um=new UserManagerImpl(); LogHandler log =new LogHandler(um); um=ProxyUtil.proxyOne(um.getClass().getClassLoader(), um.getClass().getInterfaces(), log); TimeHandler time = new TimeHandler(um); um=ProxyUtil.proxyOne(um.getClass().getClassLoader(), um.getClass().getInterfaces(), time); um.addUser("1111", "張三"); }
為了示範(fàn)需要,這邊又增加了一個(gè)LogHandler,跟TimeHandler程式碼一樣。
CGLIB動(dòng)態(tài)代理程式模擬
CGLIB動(dòng)態(tài)代理程式的兩個(gè)核心介面(類別)分別是MethodInterceptor和Enhancer。是不是跟JDK動(dòng)態(tài)代理很相似,用法也差不多。但CGLIB可以代理類別和介面。注意:不能代理final類別。
public class TimeInterceptor implements MethodInterceptor { private Object target; public TimeInterceptor(Object target) { this.target = target; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy invocation) throws Throwable { System.out.println("方法之前:"+System.currentTimeMillis()); Object ret = invocation.invoke(target, args); System.out.println("方法之后:"+System.currentTimeMillis()); return ret; } }
intercept方法4個(gè)參數(shù)。 1.產(chǎn)生的代理類別實(shí)例。 2.被代理物件的方法引用。 3.方法參數(shù)值數(shù)組。 4.代理類別對(duì)方法的代理引用。
public class ProxyUtil { @SuppressWarnings("unchecked") public static <T> T proxyOne(Class<?> clz,MethodInterceptor interceptor){ return (T)Enhancer.create(clz, interceptor); } }
Enhancer類別是CGLib中的字節(jié)碼增強(qiáng)器。
public class UserManage { public void addUser(String userId, String userName) { System.out.println("addUser(id:"+userId+",name:"+userName+")"); } } public static void main(String[] args) { UserManage um = new UserManage(); TimeInterceptor time = new TimeInterceptor(um); um = ProxyUtil.proxyOne(um.getClass(), time); um.addUser("111", "老王"); }
相關(guān)免費(fèi)學(xué)習(xí)推薦:java基礎(chǔ)教學(xué)
以上是spring aop原理是什麼的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)