1. 程式人生 > >Spring 通過XML配置檔案以及通過註解形式來AOP 來實現前置,環繞,異常通知,返回後通知,後通知

Spring 通過XML配置檔案以及通過註解形式來AOP 來實現前置,環繞,異常通知,返回後通知,後通知

本節主要內容:

一、Spring 通過XML配置檔案形式來AOP 來實現前置,環繞,異常通知


    1. Spring AOP  前置通知 XML配置使用案例

    2. Spring AOP  環繞通知 XML配置使用案例

    3. Spring AOP  丟擲異常後通知 XML配置使用案例

    4. Spring AOP  返回後通知 XML配置使用案例

    5. Spring AOP  後通知  XML配置使用案例

二、Spring 通過註解形式來AOP 來實現前置,環繞,異常通知


    1. Spring AOP  前置通知  註解使用案例

    2. Spring AOP  環繞通知  註解

使用案例

    3. Spring AOP  丟擲異常後通知  註解使用案例

    4. Spring AOP  返回後通知  註解使用案例

    5. Spring AOP  後通知  註解使用案例

本文作者:souvc

AOP是Aspect Oriented Programming的縮寫,意思是面向方面程式設計,AOP實際是GoF設計模式的延續

關於Spring AOP的一些術語

  • 切面(Aspect):在Spring AOP中,切面可以使用通用類或者在普通類中以@Aspect 註解(@AspectJ風格)來實現
  • 連線點(Joinpoint):在Spring AOP中一個連線點代表一個方法的執行
  • 通知(Advice):在切面的某個特定的連線點(Joinpoint)上執行的動作。通知有各種型別,其中包括"around"、"before”和"after"等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 並維護一個以連線點為中心的攔截器鏈
  • 切入點(Pointcut):定義出一個或一組方法,當執行這些方法時可產生通知,Spring預設使用AspectJ切入點語法。

通知型別

  • 前置通知(@Before):在某連線點(join point)之前執行的通知,但這個通知不能阻止連線點前的執行(除非它丟擲一個異常)
  • 返回後通知(@AfterReturning):在某連線點(join point)正常完成後執行的通知:例如,一個方法沒有丟擲任何異常,正常返回
  • 丟擲異常後通知(@AfterThrowing):方法丟擲異常退出時執行的通知
  • 後通知(@After):當某連線點退出的時候執行的通知(不論是正常返回還是異常退出)
  • 環繞通知(@Around):包圍一個連線點(join point)的通知,如方法呼叫。這是最強大的一種通知型別,環繞通知可以在方法呼叫前後完成自定義的行為,它也會選擇是否繼續執行連線點或直接返回它們自己的返回值或丟擲異常來結束執行

Spring 實現AOP是依賴JDK動態代理和CGLIB代理實現的。以下是JDK動態代理和CGLIB代理簡單介紹
   

    JDK動態代理:其代理物件必須是某個介面的實現,它是通過在執行期間建立一個介面的實現類來完成對目標物件的代理。
    CGLIB代理:實現原理類似於JDK動態代理,只是它在執行期間生成的代理物件是針對目標類擴充套件的子類。CGLIB是高效的程式碼生成包,底層是依靠ASM(開源的java位元組碼編輯類庫)操作位元組碼實現的,效能比JDK強。   

    在Spring中,有介面時將採用JDK的方式實現proxy代理物件,當沒有介面時,將採用cglib中的方式實現prixy代理物件。

一、 Spring 通過XML配置檔案形式來AOP 來實現前置,環繞,異常通知

1 Spring AOP前置通知案例

1.1 問題

使用Spring AOP前置通知,在訪問Controller中每個方法前,記錄使用者的操作日誌。

1.2 方案

Spring AOP使用步驟:

1.3 步驟

實現此案例需要按照如下步驟進行。

步驟一:建立Controller,建立新專案SpringAOP。

匯入Spring 環境的jar包 :

如果沒有jar包,那麼可以上去上面下一個。下載地址:http://yunpan.cn/cdXTcJtZfJqQk  訪問密碼 6c96

建立員工業務控制器EmpController,並實現員工查詢,程式碼如下:

複製程式碼

package com.souvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * 控制類  
 *
 */
@Controller
@RequestMapping("/emp")
public class EmpController {
    
    /**
    * 方法名:find</br>
    * 詳述: 查詢員工  </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @param userid
    * @param password
    * @return
    * @throws
     */
    @RequestMapping("/findEmp.do")
    public String find(String userid,String password) {
        
        // 模擬查詢員工資料
        System.out.println("執行,find()方法,查詢員工資料,傳送至列表頁面.");
        
        return "emp/emp_list.jsp";
    }
}

複製程式碼

步驟二:建立方面元件

建立方面元件OperateLogger,並在該類中建立記錄使用者操作日誌的方法,程式碼如下:

複製程式碼

package com.souvc.aspect;

/**
 * 用於記錄日誌的方面元件,演示Spring AOP的各種通知型別。
 */
public class OperateLogger {
    
    /**
    * 方法名:log1</br>
    * 詳述:測試前置通知 </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @throws
     */
    public void log1() {
        // 記錄日誌
        System.out.println("進入log1()方法");
    }
}

複製程式碼

步驟三:宣告方面元件

在applicationContext.xml中,宣告該方面元件,關鍵程式碼如下:

     <!-- 宣告方面元件 -->  

    <bean id="operateLogger" class="com.souvc.aspect.OperateLogger"/>

步驟四:將方面元件作用到目標元件上

在applicationContext.xml中,將宣告的方面元件作用到com.souvc.controller包下所有類的所有方法上,關鍵程式碼如下:

複製程式碼

    <!-- 宣告方面元件 -->
    <bean id="operateLogger" class="com.souvc.aspect.OperateLogger"/>
    
    <!-- 配置AOP -->
    <aop:config>
        <aop:aspect ref="operateLogger">
            <aop:before method="log1" pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
    </aop:config> 

複製程式碼

步驟五:測試

建立Junit測試類TestEmpController,並增加測試查詢員工的方法,程式碼如下:

複製程式碼

package com.souvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * 控制類  
 *
 */
@Controller
@RequestMapping("/emp")
public class EmpController {
    
    /**
    * 方法名:find</br>
    * 詳述: 查詢員工  </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @param userid
    * @param password
    * @return
    * @throws
     */
    @RequestMapping("/findEmp.do")
    public String find(String userid,String password) {
        
        // 模擬查詢員工資料
        System.out.println("執行,find()方法,查詢員工資料,傳送至列表頁面.");
        
        return "emp/emp_list.jsp";
    }
}

複製程式碼

執行該測試方法,控制檯輸出效果:

進入log1()方法
執行,find()方法,查詢員工資料,傳送至列表頁面.

可見,在執行EmpController.find()方法之前,執行了方面元件的記錄日誌的方法,由於該方法採用AOP面向物件的思想實現的,因此不需要對Controller類做任何改動。

2 Spring AOP環繞通知案例

2.1 問題

使用Spring AOP環繞通知,在訪問Controller中每個方法前,記錄使用者的操作日誌。

2.2 方案

Spring AOP使用步驟:

2.3 步驟

實現此案例需要按照如下步驟進行。

步驟一:建立方面元件

複用方面元件OperateLogger,在該類中建立新的記錄日誌的方法log2,程式碼如下:

複製程式碼

/**
    * 方法名:log2</br>
    * 詳述:環繞通知使用的方法 </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @param p
    * @return
    * @throws Throwable
    * @throws
     */
    public Object log2(ProceedingJoinPoint p) throws Throwable {
        // 目標元件的類名
        String className = p.getTarget().getClass().getName();
        // 呼叫的方法名
        String method = p.getSignature().getName();
        // 當前系統時間
        String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date());
        // 拼日誌資訊
        String msg = "-->使用者在" + date + ",執行了" + className + "." + method + "()";
        // 記錄日誌
        System.out.println(msg);
        // 執行目標元件的方法
        Object obj = p.proceed();
        // 在呼叫目標元件業務方法後也可以做一些業務處理
        System.out.println("-->呼叫目標元件業務方法後...");
        return obj;
    }

複製程式碼

步驟二:宣告方面元件

由於複用的方面元件已經宣告,因此該步驟可以省略。

步驟三:將方面元件作用到目標元件上

在applicationContext.xml中,宣告方面元件的log2方法,關鍵程式碼如下:

<aop:aspect ref="operateLogger">
   <aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
 </aop:aspect>

 步驟四:測試

執行測試方法TestEmpController.test1(),控制檯輸出效果如下:

進入log1()方法
-->使用者在2016-04-29 01:06:54,執行了com.souvc.controller.EmpController.find()
執行,find()方法,查詢員工資料,傳送至列表頁面.
-->呼叫目標元件業務方法後..

專案詳細程式碼:

applicationContext.xml

複製程式碼

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
            http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <!-- 開啟註解掃描 -->
    <context:component-scan base-package="com.souvc" />

    <!-- 支援@RequestMapping請求和Controller對映 -->
    <mvc:annotation-driven />
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 宣告方面元件--> 
    <bean id="operateLogger" class="com.souvc.aspect.OperateLogger" />

      <!-- 配置AOP -->
    <aop:config>
    
         <!-- 測試前置通知 -->
        <aop:aspect ref="operateLogger">
            <aop:before method="log1"  pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        
        <!-- 測試環繞通知 -->
        <aop:aspect ref="operateLogger">
            <aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        
        
    </aop:config> 
    
    
   
    
</beans>

複製程式碼

OperateLogger.java

複製程式碼

package com.souvc.aspect;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 用於記錄日誌的方面元件,演示Spring AOP的各種通知型別。
 */
public class OperateLogger {
    
    /**
    * 方法名:log1</br>
    * 詳述:測試前置通知 </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @throws
     */
    public void log1() {
        // 記錄日誌
        System.out.println("進入log1()方法");
    }
    
    
    
    /**
    * 方法名:log2</br>
    * 詳述:環繞通知使用的方法 </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @param p
    * @return
    * @throws Throwable
    * @throws
     */
    public Object log2(ProceedingJoinPoint p) throws Throwable {
        // 目標元件的類名
        String className = p.getTarget().getClass().getName();
        // 呼叫的方法名
        String method = p.getSignature().getName();
        // 當前系統時間
        String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date());
        // 拼日誌資訊
        String msg = "-->使用者在" + date + ",執行了" + className + "." + method + "()";
        // 記錄日誌
        System.out.println(msg);
        // 執行目標元件的方法
        Object obj = p.proceed();
        // 在呼叫目標元件業務方法後也可以做一些業務處理
        System.out.println("-->呼叫目標元件業務方法後...");
        return obj;
    }

}

複製程式碼

3 Spring AOP異常通知案例

3.1 問題

使用Spring AOP異常通知,在每個Controller的方法發生異常時,記錄異常日誌。

3.2 方案

Spring AOP使用步驟:

3.3 步驟

實現此案例需要按照如下步驟進行。

步驟一:建立方面元件

複用方面元件OperateLogger,在該類中建立新的記錄日誌的方法log3,程式碼如下:

複製程式碼

 /**
   * 方法名:log3</br>
   * 詳述:測試異常通知使用的方法</br>
   * 開發人員:http://www.cnblogs.com/liuhongfeng/  </br>
   * 建立時間:2016年4月29日  </br>
   * @param e
   * @throws
    */
    public void log3(Exception e) {
        StackTraceElement[] elems = e.getStackTrace();
        // 將異常資訊記錄
        System.out.println("-->" + elems[0].toString());
    }

複製程式碼

步驟二:宣告方面元件

由於複用的方面元件已經宣告,因此該步驟可以省略。

步驟三:將方面元件作用到目標元件上

在applicationContext.xml中,宣告方面元件的log3方法,關鍵程式碼如下:

 <aop:aspect ref="operateLogger">
            <aop:after-throwing method="log3" throwing="e" pointcut="within(com.souvc.controller..*)"/>
 </aop:aspect>

關鍵配置程式碼:

複製程式碼

<!-- 開啟註解掃描 -->
    <context:component-scan base-package="com.souvc" />

    <!-- 支援@RequestMapping請求和Controller對映 -->
    <mvc:annotation-driven />
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 宣告方面元件--> 
    <bean id="operateLogger" class="com.souvc.aspect.OperateLogger" />

      <!-- 配置AOP -->
    <aop:config>
    
         <!-- 測試前置通知 -->
        <aop:aspect ref="operateLogger">
            <aop:before method="log1"  pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        
        <!-- 測試環繞通知 -->
        <aop:aspect ref="operateLogger">
            <aop:around method="log2" pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        
        <!-- 測試異常通知 -->
         <aop:aspect ref="operateLogger">
            <aop:after-throwing method="log3" throwing="e" pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        
    </aop:config> 

複製程式碼

步驟四:測試

為了便於測試,在EmpController.find()方法中製造一個異常,程式碼如下:

主要程式碼:

 // 製造一個異常,便於測試異常通知
        //Integer.valueOf("abc");

 五、測試效果

進入log1()方法
-->使用者在2016-04-29 01:12:07,執行了com.souvc.controller.EmpController.find()
執行,find()方法,查詢員工資料,傳送至列表頁面.
-->java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

4 Spring AOP  後返回通知案例

4.1 問題

使用Spring AOP後返回通知型別。

4.2 方案

Spring AOP使用步驟:

4.3 步驟

實現此案例需要按照如下步驟進行。

5 Spring AOP  執行後案例

5.1 問題

使用Spring AOP 執行後通知型別。

5.2 方案

Spring AOP使用步驟:

5.3 步驟

實現此案例需要按照如下步驟進行。

步驟一:

在 OperateLogger.java 新增以下程式碼:

複製程式碼

 /**
     * 方法名:log5</br>
     * 詳述:測試 執行後使用的方法</br>
     * 開發人員:http://www.cnblogs.com/liuhongfeng/  </br>
     * 建立時間:2016年4月29日  </br>
     * @param result
     * @return
     * @throws
      */
    public void log5() {
        // 記錄日誌
        System.out.println("進入log5()方法");
    }

複製程式碼

步驟二:

在 applicationContext.xml 新增以下程式碼:

<!-- 測試後通知 -->
  <aop:aspect ref="operateLogger">
       <aop:after method="log5"  pointcut="within(com.souvc.controller..*)"/>
  </aop:aspect>

步驟三:

執行測試類

步驟四:

效果如下:

進入log1()方法
-->使用者在2016-04-29 01:53:10,執行了com.souvc.controller.EmpController.find()
執行,find()方法,查詢員工資料,傳送至列表頁面.
進入log5()方法
-->java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

二、 Spring 通過註解形式形式來AOP 來實現前置,環繞,異常通知

Spring AOP相關注解及含義如下:

@Aspect:用於宣告方面元件

@Before:用於宣告前置通知

@AfterReturning:用於聲明後置通知

@After:用於宣告最終通知

@Around:用於宣告環繞通知

@AfterThrowing:用於宣告異常通知

1 Spring AOP註解使用案例

1.1 問題

使用Spring AOP註解替代XML配置,重構上面的3個案例。

1.2 方案

分別在對應的方法上面加上註解。

1.3 步驟

實現此案例需要按照如下步驟進行。

步驟一:開啟AOP註解掃描

在applicationContext.xml中,去掉方面元件宣告及作用的XML配置,並開啟AOP註解掃描,關鍵程式碼如下:

複製程式碼

<!-- 宣告方面元件 -->
    <!-- <bean id="operateLogger" class="com.souvc.aspect.OperateLogger" />-->

    <!-- 配置AOP -->
    
    <!--  <aop:config>
        <aop:aspect ref="operateLogger">
            <aop:before method="log1" pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        <aop:aspect ref="operateLogger">
            <aop:around method="log2"  pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
        <aop:aspect ref="operateLogger">
            <aop:after-throwing method="log3" throwing="e" pointcut="within(com.souvc.controller..*)"/>
        </aop:aspect>
     </aop:config>    -->

複製程式碼

<!-- 開啟AOP註解掃描 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

或者:

<!-- 啟用spring對AspectJ註解的支援 -->  
    <aop:aspectj-autoproxy/>

步驟二:使用註解宣告方面元件

在OperateLogger中,使用@Aspect註解宣告方面元件,並分別用@Before、@Around、@AfterThrowing註解宣告log1、log2、log3方法,將方面元件作用到目標元件上,程式碼如下:

複製程式碼

package com.souvc.aspect;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 用於記錄日誌的方面元件,演示Spring AOP的各種通知型別。
 */
@Component
@Aspect
public class OperateLogger {
    
    /**
    * 方法名:log1</br>
    * 詳述:測試前置通知 </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @throws
     */
     @Before("within(com.souvc.controller..*)")
    public void log1() {
        // 記錄日誌
        System.out.println("進入log1()方法");
    }
    
    
    
    /**
    * 方法名:log2</br>
    * 詳述:環繞通知使用的方法 </br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/ </br>
    * 建立時間:2016年4月29日  </br>
    * @param p
    * @return
    * @throws Throwable
    * @throws
     */
     @Around("within(com.souvc.controller..*)")
    public Object log2(ProceedingJoinPoint p) throws Throwable {
        // 目標元件的類名
        String className = p.getTarget().getClass().getName();
        // 呼叫的方法名
        String method = p.getSignature().getName();
        // 當前系統時間
        String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") .format(new Date());
        // 拼日誌資訊
        String msg = "-->使用者在" + date + ",執行了" + className + "." + method + "()";
        // 記錄日誌
        System.out.println(msg);
        // 執行目標元件的方法
        Object obj = p.proceed();
        // 在呼叫目標元件業務方法後也可以做一些業務處理
        System.out.println("-->呼叫目標元件業務方法後...");
        return obj;
    }

    
    
    
   /**
   * 方法名:log3</br>
   * 詳述:測試異常通知使用的方法</br>
   * 開發人員:http://www.cnblogs.com/liuhongfeng/  </br>
   * 建立時間:2016年4月29日  </br>
   * @param e
   * @throws
    */
     @AfterThrowing(pointcut = "within(com.souvc.controller..*)", throwing = "e")
    public void log3(Exception e) {
        StackTraceElement[] elems = e.getStackTrace();
        // 將異常資訊記錄
        System.out.println("-->" + elems[0].toString());
    }
    
    
    /**
    * 方法名:log4</br>
    * 詳述:測試 返回後通知使用的方法</br>
    * 開發人員:http://www.cnblogs.com/liuhongfeng/  </br>
    * 建立時間:2016年4月29日  </br>
    * @param result
    * @return
    * @throws
     */
     @AfterReturning(value="execution(* com.souvc.controller.*.*(..))",returning="result")
    public void log4(JoinPoint joinPoint,Object result ){
        Object object = joinPoint.getSignature();//方法返回值
       
        System.out.println("joinPoint.getKind():"+ joinPoint.getKind());
        System.out.println("joinPoint.getTarget():"+joinPoint.getTarget());
        System.out.println("joinPoint.getThis():"+joinPoint.getThis());
        System.out.println("joinPoint.getArgs():"+joinPoint.getArgs().length);
        Object [] args=joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            System.out.println("引數:"+args[i]);
        }
        System.out.println("joinPoint.getSignature():"+joinPoint.getSignature());
        System.out.println("joinPoint.getSourceLocation():"+joinPoint.getSourceLocation());
        System.out.println("joinPoint.getStaticPart():"+joinPoint.getStaticPart());
      
        String rightnow=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
        System.out.println(rightnow+"執行了【"+object+"方法正常執行結束......】"+"【返回結果:"+result+"】"); 
    }
    
    
    
    /**
     * 方法名:log5</br>
     * 詳述:測試 執行後使用的方法</br>
     * 開發人員:http://www.cnblogs.com/liuhongfeng/  </br>
     * 建立時間:2016年4月29日  </br>
     * @param result
     * @return
     * @throws
      */
//    @After(value="execution(com.souvc.controller.*.*(..))")
//    public void log5() {
//        // 記錄日誌
//        System.out.println("進入log5()方法");
//    }
    
    
    
}

複製程式碼

步驟三:測試

執行測試方法TestEmpController.test1(),結果如下:

無異常的時候:

-->使用者在2016-04-27 11:30:22,執行了com.souvc.controller.EmpController.find()
-->記錄使用者操作資訊
查詢員工資料,傳送至列表頁面.
-->呼叫目標元件業務方法後...

 有異常的時候:

-->使用者在2016-04-27 11:32:27,執行了com.souvc.controller.EmpController.find()
-->記錄使用者操作資訊
查詢員工資料,傳送至列表頁面.
-->java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

1)JoinPoint 


java.lang.Object[] getArgs():獲取連線點方法執行時的入參列表; 
Signature getSignature() :獲取連線點的方法簽名物件; 
java.lang.Object getTarget() :獲取連線點所在的目標物件; 
java.lang.Object getThis() :獲取代理物件本身; 


2)ProceedingJoinPoint 


ProceedingJoinPoint繼承JoinPoint子介面,它新增了兩個用於執行連線點方法的方法: 
java.lang.Object proceed() throws java.lang.Throwable:通過反射執行目標物件的連線點處的方法; 
java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執行目標物件連線點處的方法,不過使用新的入參替換原來的入參。  

本文作者:souvc

其他的博文可以參考:

相關推薦

Spring 通過XML配置檔案以及通過註解形式AOP 實現前置環繞異常通知返回通知通知

本節主要內容: 一、Spring 通過XML配置檔案形式來AOP 來實現前置,環繞,異常通知     1. Spring AOP  前置通知 XML配置使用案例     2. Spring AOP  環繞通知 XML配置使用案例     3. Spring AOP

Springxml配置檔案或annotation註解中運用Spring EL

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins

Springxml配置檔案 或 annotation 註解中 運用Spring EL

三月 18, 2013 5:25:23 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org[email protected]11e831: star

Spring mvc通過xml配置檔案方式實現簡單HelloWorld

實現Spring MVC有兩種不同的方式:基於XML配置檔案和基於註解。 這裡,我們使用XML檔案的方式來實現。 首先,我們需要在Eclipse或者是MyEclipse中新建一個web專案,並將Spr

Spring-通過xml配置檔案實現切面(AOP)

使用註解的方式實現AOP: 1、業務類 PersonService.java/* *@Author swxctx *@time 2016年9月22日 */ package com.sw.serv

Spring ApplicationContext.xml 配置檔案常用註解和詳解

ApplicationContext.xml <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans"

讓Eclipse中springxml配置檔案出現屬性和類提示

在spring配置檔案中可以讓配置bean的時候出現提示,這裡需要做一些設定。設定包括安裝springide外掛,spring-beans-version.xsd檔案引入,增加xml編輯提示的字元,預設只有=>:。最後是讓配置檔案可以通過Spring Config Editor的方式開

springxml配置宣告以及相應的問題處理

spring的xml配置宣告:  xml配置宣告 Code 問題處理 問題1   xml報錯: cvc-elt.1: Cannot find the declaration of element 'beans'. 問題分析   該問題就是找不到對應的spring-be

Spring Cloud 第六篇:spring cloud 整合 配置檔案以及 mybatis

在上幾篇 專案的基礎上來修改服務程式碼。 首先修改,service-hi 專案(服務提供方),pom.xml檔案如下 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave

Spring Boot: Yaml配置檔案 以及 @ConfigurationProperties屬性獲取

Yaml配置檔案 概述 Spring Boot在支援application.properties配置檔案的同時,也支援application.yaml配置檔案. 配置檔案中的屬性,可以通過: 通過@Value註解將屬性值注入Bean中; 通過@ConfigurationProperties註解

Eclipse中Springxml配置檔案提示類屬性值的配置

在開發Spring專案時,發現在配置xml檔案時,class類的屬性值一直都不提示,這樣很容易導致引用的包名寫錯。因此我通過床上看資料,總結了下面的配置方法。 一、檢視Eclipse的版本號 方法一:檢視自己的安裝包 方法二:開啟Eclipse軟體,點選Help—>About

3.dubbo.properties代替springxml配置檔案

1.介紹 如果公共配置很簡單無多註冊中心,無多協議情況下或者想要多個spring容器共享一個公共的配置就可以用dubbo.propertis檔案作為預設配置。dubbo將自動載入classpath下面的dubbo.properties。可以通過jvm啟動引數-Dubbo.p

Spring 載入xml配置檔案的方式 ApplicationContext

       大家都知道Java讀普通檔案是通過Basic I/O 中的InputStream、OutStream、Reader、Writer 等實現的。在spring 框架中,它是怎樣識別xml這個配置檔案的呢? 這就要靠IoC容器的兩個介面BeanFactory 和Ap

web.xml中定義的SpringXML配置檔案啟動順序

在web.xml中定義的Spring的配置檔案一般有兩個: 1、Spring上下文環境的配置檔案:applicationContext.xml <context-param> <param-name>conte

Spring通過XML配置c3p0連線池和dao層註解注入使用 jdbcTemplate

Spring通過註解配置c3p0連線池和dao使用 jdbcTemplate 1.Spring配置c3p0連線池 第一步:匯入c3p0的jar包 第二步:建立Spring配置檔案,配置連線池 平常我們寫c3p0連線池時是這樣寫的:

Spring載入Properties配置檔案java通過註解讀取資料

 1、用法示例: 在springMVC.xml配置檔案中新增標籤 (推薦用這個,這個用的比較多,也比較簡潔) <context:property-placeholder location="classpath:salesman.properties"/>

spring boot 入門1-----如何使用@Value註解讀取配置檔案以及使用@ConfigrationProperties註解

讀取.yml檔案屬性值的方式    1)如何將配置檔案中的屬性值與欄位匹配起來         @Value("${配置檔案中屬性的名}")       在application.yml檔案中   &n

Spring 通過XML配置裝配Bean

使用XML裝配Bean需要定義對於的XML,需要引入對應的XML模式(XSD)檔案,這些檔案會定義配置Spring Bean的一些元素,簡單的配置如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.s

Lunix下tomcat通過配置server.xml配置檔案實現執行非webapps目錄下的專案

1、首先普及一個觀點:tomcat對於webapps下的專案會自動部署,不需要配置server.xml,但對於非webapps目錄下的專案則需要手動配置server.xml檔案,例如在搭建nginx伺服器均衡負載時,往往不會把專案放在webapps目錄下。 2、serv

Spring 學習筆記(五)IOC之零註解配置(用註解代替applicationContext.xml配置檔案

有了這個東西開發方便很多,不用寫xml那些配置嘍。 package org.spring.exampleAOP; import org.springframework.context.annotation.ComponentScan; import org.springframework.co