更新時間:2022-07-04 11:33:45 來源:動力節點 瀏覽1676次
AOP的全稱是面向方面編程,即面向方面編程。它是面向對象編程(OOP)的補充。目前已經成為一種比較成熟的編程方式。
在傳統的業務處理代碼中,通常會進行事務、日志等操作。雖然使用OOP可以通過組合或者繼承來實現代碼復用,但是如果要實現一個功能(比如日志),同樣的代碼還是會分散在各種方法中。這樣,如果你想關閉一個功能或者修改它,你必須修改所有相關的方法。這不僅增加了開發者的工作量,也提高了代碼的錯誤率。
為了解決這個問題,AOP的想法應運而生。AOP采用橫向抽取機制,將分散在各種方法中的重復代碼抽取出來,然后在程序編譯或運行時將抽取出來的代碼應用到需要執行的地方。采用橫向抽取機制和傳統的OOP思想顯然是不可能的,因為OOP只能實現父子關系的縱向復用。雖然 AOP 是一種新的編程思想,但它并不能替代 OOP。它只是OOP的擴展和補充。
AOP 在編寫業務邏輯時,開發人員可以專注于核心業務,而不必過多關注其他業務邏輯的實現,不僅提高了開發效率,還增強了代碼的可維護性。
目前最流行的AOP框架有兩種:spring AOP和AspectJ。Spring AOP 是用純 Java 實現的,沒有特殊的編譯過程和類加載器。增強代碼在運行時通過代理編織到目標類中。AspectJ 是一個基于 Java 語言的 AOP 框架,從 spring 2.0 開始,spring AOP 引入了對 AspectJ 的支持,它擴展了 Java 語言,并提供了一個特殊的編譯器,在編譯時提供橫向代碼編織。
Aspect:在實際應用中,Aspect通常是指用于橫向插入系統功能(如事務、日志等)的封裝類。要被Spring容器識別為切面,需要通過配置文件中的元素來指定。
Joinpoint:在程序執行過程中的某個階段,實際上是對一個對象的操作,比如方法調用或者異常拋出。在 Spring AOP 中,連接點是一個方法調用。
切入點:指切面與程序流的交集,即需要處理的連接點。通常在程序中,切入點是指類或方法名。如果要對所有以 add 開頭的方法應用通知,則所有符合該規則的方法都是切入點。
Advice:AOP框架在特定切入點處進行的增強處理,即在定義的切入點處要執行的程序代碼。可以理解為切面類中的方法,是切面的具體實現。
目標對象:指所有被通知的對象,也稱為增強對象。如果AOP框架采用動態AOP實現,那么對象就是代理對象。
代理:通知應用到目標對象后動態創建的對象。
編織:將切片代碼插入目標對象以生成代理對象的過程。
1.創建web工程,將Spring框架需要的JAR包導入到工程lib目錄下,發布到類路徑下。
2.在src目錄下,創建一個包(比如我創建的yjf.jdk),在包下創建接口UserDao.java
包yjf.jdk;
公共接口 UserDao {
公共無效添加用戶();
公共無效刪除用戶();
}
3.在yjf.jdk包中,創建UserDao接口實現的類UserDaoImpl.java,分別實現接口中的方法
包yjf.jdk;
公共類 UserDaoImpl 實現 UserDao {
公共無效添加用戶(){
System.out.println("添加用戶");
}
公共無效刪除用戶(){
System.out.println("刪除用戶");
}
}
4.在src目錄下再創建一個包(比如我創建的yjf.aspect包),在包下創建切面類MyAspect.java。在這個類中,定義一個檢查模擬權限的方法和一個模擬日志記錄的方法。這兩個方法是方面的通知
包yjf.aspect;
公共類 MyAspect {
公共無效 check_Permissions(){
System.out.println("模擬檢查權限......");
}
公共無效日志(){
System.out.println("模擬日志......");
}
}
5.在yjf.jdk包下,創建Proxy類JdkProxy,需要實現InvocationHandler接口,編寫Proxy方法。在Proxy方法中,需要通過Proxy類實現動態Proxy
包yjf.jdk;
導入 java.lang.reflect.InvocationHandler;
導入java.lang.reflect.Method;
導入 java.lang.reflect.Proxy;
導入 yjf.aspect.*;
/* JDK 代理類 */
公共類 JdkProxy 實現 InvocationHandler {
//聲明目標類接口
私人用戶道用戶道;
//創建代理方法
公共對象 createProxy(UserDao userDao){
this.userDao = userDao;
//1. 類加載器
類加載器 classLoader = JdkProxy.class.getClassLoader();
//2。代理對象實現的所有接口
類[] clazz = userDao.getClass().getInterfaces();
//3. 使用代理類增強代理后返回對象
return Proxy.newProxyInstance(classLoader, clazz, this);
}
/*
* 動態代理類的所有方法調用都由invoke()方法處理
* 被表示后的代理對象
* method 要執行的方法信息(反射)
* asgs 執行方法所需的參數
*
* */
@覆蓋
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
//聲明部分
MyAspect myAspect = new MyAspect();
//預增強
myAspect.check_Permissions();
//調用目標類上的方法并傳入參數
對象 obj = method.invoke(userDao, args);
//侯增強
myAspect.log();
返回對象;
}
}
6.在yjf.jdk包中,創建測試類JdkTest,在該類中創建代理對象和目標對象,然后從代理對象中獲取目標對象userDao增強的對象,最后調用add和delete方法在對象中。
包yjf.jdk;
公共類 JdkTest {
公共靜態無效主要(字符串[]參數){
//創建代理對象
JdkProxy jdkProxy = new JdkProxy();
//創建目標對象
UserDao userDao = new UserDaoImpl();
//從代理對象中獲取增強的目標對象
UserDao userDao1 = (UserDao) jdkProxy.createProxy(userDao);
//執行方法
userDao1.addUser();
userDao1.deleteUser();
}
}
運行結果為:
模擬檢查權限......
添加用戶
模擬日志……
模擬檢查權限......
刪除用戶
模擬日志……
可以看到userDao實例中添加和刪除用戶的方法已經成功調用,調用前后增加了查看權限和記錄權限的功能。這是 Spring動態代理。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習