首頁 >Java >Java基礎 >spring aop原理是什麼

spring aop原理是什麼

coldplay.xixi
coldplay.xixi原創
2020-10-30 14:51:073390瀏覽

spring aop原理:1、AOP 面向切面,是一種程式設計範式,提供從另一個角度來考慮程式結構以完善物件導向程式設計OOP;2、AOP為開發者提供了一種描述橫切關注點的機制,並且能夠自動將橫切關注點織入到物件導向的軟體系統中。

spring 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):需要被織入關注點的物件。即被代理的對象。

spring aop原理是什麼

實作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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn