Spring入門筆記之Aop
Spring入門筆記之Aop
——2018年11月22日
Aop(Aspect Oriented Programming),即面向切面程式設計,可以說是對oop(Object Oriented Programming),即面向物件程式設計的補充和完善。Aop的存在就是讓大量程式碼重複使用,將各個模組重用。
所謂“切面”,簡單來說就是那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性。
AOP核心概念
- 橫切關注點
對哪些方法進行攔截,攔截後怎麼處理,這些關注點稱之為橫切關注點。
- 切面(aspect)
類是對物體特徵的抽象,切面就是對橫切關注點的抽象
- 連線點(join point)
被攔截到的點,因為Spring只支援方法型別的連線點,所以在Spring中連線點指的就是被攔截到的方法,實際上連線點還可以是欄位或者構造器.
4、切入點(pointcut)
對連線點進行攔截的定義
5、通知(advice)
所謂通知指的就是指攔截到連線點之後要執行的程式碼,通知分為前置、後置、異常、最終、環繞通知五類
6、目標物件
代理的目標物件
7、織入(weave)
將切面應用到目標物件並導致代理物件建立的過程
8、引入(introduction)
在不修改程式碼的前提下,引入可以在執行期為類動態地新增一些方法或欄位.
程式碼瞭解階段:
Spring AOP代理物件的生成
Xml配置方式:
- 把目標方法所有類和切面類放入ioc容器中。
- 配置<aop:config>
這裡著重解釋講解第二種方式(註解)
步驟:
- spring框架中我們可以使用基於AspectJ註解來配置Aop(最主流)
簡單理解就是,AspectJ就是一個支援AOP的第三方元件,Spring提供了很好的支援,首先需要引入Maven依賴。
- 在配置檔案中宣告 使用AspectJ註解
使AspectJ註解生效:
Util類:
package org.robert.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class Log {
/**
*宣告此方法為了程式碼重用嘛
*/
@Pointcut("execution(* org.robert.Service.*.*(..))")
public void pointcut(){
}
/**
* 前置通知
* 進入方法就執行
*/
@Before(value = "pointcut()")
public void before(){
System.out.println("進來了");
}
/**
* 後置通知
* 業務執行完成通知
* 無論是否出異常就執行
*/
@After(value = "pointcut()")
public void after(){
System.out.println("幹完了,要出去了");
}
/**
* 業務方法執行失敗就不執行
* 返回通知
* 獲取返回的值
// 宣告該方法為返回通知:方法正常執行結束後執行的程式碼
// 返回 通知是可以訪問到方法的返回值的!
/*切點表示式表示執行任意類的任意方法. 第
一個 * 代表匹配任意修飾符及任意返回值, 第二個 * 代表任意類的物件,
第三個 * 代表任意方法, 引數列表中的 .. 匹配任意數量的引數
*/
*/
@AfterReturning(value = "pointcut()",returning = "val")
public void success(Object val){
System.out.println("業務執行成功"+val);
}
/**
* 異常通知
* 出異常就執行
*/
@AfterThrowing(value = "pointcut()",throwing = "val")
public void testexception(Throwable val){
System.out.println("出異常啦"+val.getMessage());
}
/**
* 環繞通知
* 功能雖然強大,但用得少
*/
//@Around(value = "pointcut()")
public Object arroud(ProceedingJoinPoint pdj){
//前置
Object result = null;
try {
//執行目標方法
result = pdj.proceed();
} catch (Throwable e) {
//異常
e.printStackTrace();
}
//後置
return result;
}
}
Service類:
package org.robert.Service;
import org.robert.mapper.StudentMapper;
import org.springframework.stereotype.Service;
@Service
public class StudentService {
StudentMapper studentMapper;
public void testService() {
System.out.println(studentMapper);
}
public Integer insert(){
System.out.println("業務程式碼插入資料");
//System.out.println(2/0);
return 100;
}
public void delete(){
System.out.println("業務程式碼刪除資料");
}
}