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", "老王"); }
相關免費學習推薦:java基礎教學
以上是spring aop原理是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!