小編給大家分享一下spring aop工作原理,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
spring aop原理:1、AOP 面向切面,是一種編程范式,提供從另一個角度來考慮程序結構以完善面向對象編程OOP;2、AOP為開發者提供了一種描述橫切關注點的機制,并能夠自動將橫切關注點織入到面向對象的軟件系統中。
spring aop原理:
AOP(面向切面)是一種編程范式,提供從另一個角度來考慮程序結構以完善面向對象編程(OOP)。
AOP為開發者提供了一種描述橫切關注點的機制,并能夠自動將橫切關注點織入到面向對象的軟件系統中,從而實現了橫切關注點的模塊化。
AOP能夠將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任,例如事務處理、日志管理、權限控制等,封裝起來,便于減少系統的重復代碼,降低模塊間的耦合度,并有利于未來的可操作性和可維護性。
使用AOP的好處
降低模塊的耦合度
使系統容易擴展
提高代碼復用性
AOP的基本概念
連接點(JoinPoint):需要在程序中插入橫切關注點的點,連接點可能是在類初始化、方法調用、字段調用或處理異常等等。Spring中只支持方法執行連接點。
切入點(Pointcut):一組相關連接點的集合。
通知(Advice):在連接點上執行的行為,增強提供了在AOP中需要在切入點所選擇的連接點處進行擴展現有行為的手段。包括前置增強(before advice)、后置增強 (after advice)、環繞增強 (around advice)。
切面(Aspect):通知和切入點的結合。
織入(Weaving):織入是一個過程,是將切面應用到目標對象從而創建出AOP代理對象的過程。
代理(Proxy):通過代理方式來對目標對象應用切面。AOP代理可以用JDK動態代理或CGLIB代理實現。
目標對象(Target):需要被織入關注點的對象。即被代理的對象。
實現AOP的主要設計模式就是動態代理。
Spring的動態代理有兩種:一是JDK的動態代理;另一個是cglib動態代理。
JDK動態代理模擬
JDK動態代理的兩個核心接口(類)分別是InvocationHandler和Proxy。注意:只能代理接口。
public class TimeHandler implements InvocationHandler { // 目標對象 private Object targetObject; public TimeHandler(Object targetObject){ this.targetObject = targetObject; } @Override //關聯的這個實現類的方法被調用時將被執行 /*InvocationHandler接口的方法,proxy表示代理,method表示原對象被調用的方法, args表示方法的參數*/ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret=null; try{ System.out.println("方法之前:"+System.currentTimeMillis()); //調用目標方法 ret=method.invoke(targetObject, args); System.out.println("方法之后:"+System.currentTimeMillis()); }catch(Exception e){ e.printStackTrace(); System.out.println("error"); throw e; } return ret; } }
TimeHandler 類實現了InvocationHandler接口。實現核心方法invoke,共有3個參數。第一個參數 生成的代理類實例,第二個參數 目標對象的方法,第三個參數 方法的參數值數組。
public class ProxyUtil { @SuppressWarnings("unchecked") public static <T> T proxyOne(ClassLoader loader,Class<?>[] clz,InvocationHandler handler){ return (T)Proxy.newProxyInstance(loader, clz, handler); } }
ProxyUtil 類簡單封裝了一下Proxy.newProxyInstance()方法。該方法也有3個參數。第一個參數產生代理對象的類加載器,第二個參數目標對象的接口數組,第三個參數就是實現InvocationHandler接口的類實例。
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", "張三"); }
為了演示需要,這邊又增加了一個LogHandler,跟TimeHandler代碼一樣。
CGLIB動態代理模擬
CGLIB動態代理的兩個核心接口(類)分別是MethodInterceptor和Enhancer。是不是跟JDK動態代理很相似,用法也差不多。但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個參數。1.生成的代理類實例。2.被代理對象的方法引用。3.方法參數值數組。4.代理類對方法的代理引用。
public class ProxyUtil { @SuppressWarnings("unchecked") public static <T> T proxyOne(Class<?> clz,MethodInterceptor interceptor){ return (T)Enhancer.create(clz, interceptor); } }
Enhancer類是CGLib中的字節碼增強器。
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", "老王"); }
以上是spring aop工作原理的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。