中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Spring AOP的通知類型及創建通知

發布時間:2020-08-25 17:48:28 來源:腳本之家 閱讀:185 作者:小魚吃貓 欄目:編程語言

寫在最前端

1.SpringAOP中共有六種通知類型,只要我們自定義一個類實現對應的接口,它們全都是org.springframework.aop包中的。

2.AOP的連接點可以是方法調用、方法調用本身、類初始化、對象實例化時,但是SpringAOP中全是方法調用,更簡單,也最實用

通知名稱 接口
前置通知 org.springframework.aop.MethodBeforeAdvice
后置返回通知 org.springframework.aop.AfterReturningAdvice
后置通知 org.springframework.aop.AfterAdvice
環繞通知 org.springframework.aop.MethodInterceptor
異常通知 org.springframework.aop.ThrowsAdvice
引入通知 org.springframework.aop.IntroductionInterceptor

寫一個公共類,用于目標對象

public class Person {
 private String name;
 public boolean saySomething(String something){
  System.out.println("Pereson類中說了一句:"+something);
return true;//默認返回true
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}

一、創建前置通知(也就是目標方法調用前執行)

前置通知可以修改傳遞給方法的參數,并且可以通過拋出異常來阻止方法的執行,可以用前置通知實現用戶登錄的驗證,SpringSecurity就是這么做的

1.例子:在一個方法執行前將包含方法名稱的消息寫入到控制臺中,并且將傳入的參數修改下。(文章中寫的內容比較小,大多數在代碼中有注釋,大家可以下載代碼查看)

/**
 * 前置通知類
 */
public class BeforeAdvice implements MethodBeforeAdvice {


 @Override
 public void before(Method method, Object[] objects, @Nullable Object o) throws Throwable {
   //第一個參數是目標方法對象,第二個是參數,第三個是做為調用目標的object(這是personr實例)
  //打印方法名
  System.out.println("要執行的方法是:"+method.getName());
  //修改參數為lyn4ever
  objects[0]="lyn4ever";//我們修改成為了lyn4ever,所以打印出來的就是lyn4ever,而不是zhangsan
 }


 public static void main(String[] args) {
  Person person = new Person();

  ProxyFactory pf =new ProxyFactory();
  pf.addAdvice(new BeforeAdvice());
  pf.setTarget(person);

  Person proxy = (Person) pf.getProxy();

  //我這里傳的參數是zhangsan,理論上它應該打印出來zhangsan
  proxy.saySomething("zhangsan");
 }
}

如何使用Spring AOP的通知類型及創建通知

沒毛病,本來我輸入的是zhangsan,在aop中將參數改為了lyn4ever,這樣就完美的替換了。

二、后置返回通知

是在連接點(方法調用)返回后執行,這顯然不能像上邊那樣修改參數,也不能修改返回值。但是可以拋出可以發送到堆棧的異常,同樣也可以調用其他方法。

/**
 * 后置返回通知
 */
public class AfterReturnAdvice implements AfterReturningAdvice {

 @Override
 public void afterReturning(@Nullable Object o, Method method, Object[] objects, @Nullable Object o1) throws Throwable {
  /*
  參數和前置通知是一樣的
  這個是在返回之后調用,因此,person中的saySomething會先打印,我們在這里修改的參數不起作任何作用
   */

  System.out.println("調用的方法是:"+method.getName()+"這句是在saySomething之后");//這句是在saySomething之后
  objects[0]="lyn4ever";//這句可以修參數,但是之前的方法已經執行過了,所以不起任何作用

  System.out.println("我們修改了參數為:"+objects[0]+"但是沒有任何用");//這時候這個參數并不會傳到person.saysomething(),因為已經調用過了

 }


 public static void main(String[] args) {
  Person person = new Person();

  ProxyFactory pf = new ProxyFactory();
  pf.addAdvice(new AfterReturnAdvice());//注意修改這個為當前類中的通知類
  pf.setTarget(person);

  Person proxy = (Person) pf.getProxy();
  proxy.saySomething("zhangsan");
 }
}

如何使用Spring AOP的通知類型及創建通知

三、環繞通知

這人最好理解了,就是在方法調用前后都可以執行代碼。看起來像是前置后后置的集合,但是它可以修改方法的返回值,因為它實現的invoke方法的返回值是Object,所以我們就可以修改,而前置通知的返回是void,所以沒法修改的。甚至以至于我們可以不調用目標對象中的連接點方法,我們完全修改這個方法的全部代碼。

public class MyMethodInterceptor implements MethodInterceptor {
 @Override
 public Object invoke(MethodInvocation invocation) throws Throwable {
  return null;
 }
}

雖然這個invoke()方法中并沒有提供像之前的那些參數,但是這一個invocation實例可以得到

如何使用Spring AOP的通知類型及創建通知

如何使用Spring AOP的通知類型及創建通知

代碼示例

/**
 * 環繞通知
 */
public class MyMethodInterceptor implements MethodInterceptor {
 @Override
 public Object invoke(MethodInvocation invocation) throws Throwable {
  
  //在這個invoation中有一切我們想要的方法相關
  System.out.println("類名是:"+invocation.getThis().getClass().getName());
  System.out.println("目標方法是:"+invocation.getMethod().getName());

  Object[] arguments = invocation.getArguments();//這個就是參數
  System.out.println("第一個參數 是:"+arguments[0]);

  //我們修改第一個參數為lyn4ever
  arguments[0]="lyn4ever";


  invocation.proceed();//執行目標方法


  System.out.println("這個是在之后執行的");

  return false;//修改返回值
 }


 public static void main(String[] args) {
  Person person = new Person();

  ProxyFactory pf = new ProxyFactory();
  pf.addAdvice(new MyMethodInterceptor());//注意修改這個為當前類中的通知類
  pf.setTarget(person);

  Person proxy = (Person) pf.getProxy();
  boolean flag = proxy.saySomething("zhangsan");
  System.out.println(flag);//方法本來是要返回true的
 }
}

可以看到,我們修改了目標方法返回的值。

本文demo已提交至github

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

夏邑县| 遂溪县| 驻马店市| 舟曲县| 定远县| 巨野县| 商丘市| 瑞昌市| 尉犁县| 乐山市| 安达市| 威宁| 铅山县| 大化| 武穴市| 黄平县| 青龙| 元氏县| 古丈县| 大姚县| 金昌市| 慈溪市| 宝应县| 府谷县| 耿马| 镇宁| 镇坪县| 崇信县| 英德市| 镇江市| 德令哈市| 洛隆县| 固镇县| 桦南县| 手机| 炎陵县| 杭锦旗| 南丹县| 金平| 五河县| 钦州市|