1、基本概念
- (1)面向切面程式設計(方面),利用 AOP 可以對業務邏輯的各個部分進行隔離,進而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
- (2)通俗描述:不通過修改源代碼方式,在主幹功能裡面添加新功能
比如說、你完成了一個功能需求、後來産品經理在這個需求上增加一些新需求。你要麼修改源代碼(這個可能比較麻煩、耦合性也高)、這個時候就可以使用AOP切面程式設計、對原有的需求進行功能增強。橫切進去、就可以在不修改原先代碼的基礎上、完成新的需求(也友善後期維護、萬一産品經理說、這樣又不好呢。修改起來也容易、直接将切面拿走。)
- (3)使用登入例子說明 AOP

2、底層原理
AOP 底層使用動态代理
有兩種情況動态代理
-
第一種 有接口情況,使用 JDK 動态代理
建立接口實作類代理對象,增強類的方法
-
第二種 沒有接口情況,使用 CGLIB 動态代理
建立子類的代理對象,增強類的方法
3、JDK動态代理實作
3.1 檢視對應Proxy方法使用
1、使用 JDK 動态代理,使用 Proxy 類裡面的方法建立代理對象
開胃小知識
3.2 方法詳解
(1)調用 newProxyInstance 方法
方法有三個參數:
第一參數,類加載器
第二參數,增強方法所在的類,這個類實作的接口,支援多個接口
第三參數,實作這個接口 InvocationHandler,建立代理對象,寫增強的部分
3.3 JDK動态代理代碼
3.3.1 建立接口,定義方法
PersonDao .java
/**
* @author Lenovo
* @version 1.0
* @data 2022/10/19 22:37
*/
public interface PersonDao {
public int add(int a,int b);
public void update(int a);
}
3.3.2 建立接口實作類,實作方法
PersonDaoImpl.java
/**
* @author Lenovo
* @version 1.0
* @data 2022/10/19 22:39
*/
public class PersonDaoImpl implements PersonDao {
@Override
public int add(int a, int b) {
System.out.println("執行了add方法");
return a+b;
}
@Override
public void update(int a) {
System.out.println(a);
}
}
3.3.3 使用 Proxy 類建立接口代理對象
/**
* @author Lenovo
* @version 1.0
* @data 2022/10/19 22:40
*/
public class JdkProxy {
public static void main(String[] args) {
//建立接口實作類代理對象
Class[] interfaces = {PersonDao.class};
// Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces,
// new InvocationHandler() {
// @Override
// public Object invoke(Object proxy, Method method, Object[] args)
// throws
// Throwable {
// return null;
// }
// });
PersonDaoImpl personDao = new PersonDaoImpl();
PersonDao dao = (PersonDao) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces, new PersonDaoProxy(personDao));
int rs = dao.add(4, 5);
System.out.println("result:" + rs);
}
}
/**
* 代理對象代碼
*/
class PersonDaoProxy implements InvocationHandler {
/**
* 1 把建立的是誰的代理對象,把誰傳遞過來
* 有參數構造傳遞
*/
private Object obj;
public PersonDaoProxy(Object obj) {
this.obj = obj;
}
/**
* 增強的邏輯
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前
System.out.println("方法執行之前:" + method.getName() + ",傳遞的參數是:" + Arrays.toString(args));
//被增強的方法執行
Object rs = method.invoke(obj, args);
//方法之後
System.out.println("方法執行之後:" + obj);
return rs;
}
}