一.什麼是切面編程
切面編程(Aspect Oriented Programming,AOP)
如圖,這個驗證用戶這個子流程就成了一個條線,也可以理解成一個切面,aspect的意思就是方面.實現方式有cglib的動態代理,和jdk靜態代理.
更多理解:https://www.cnblogs.com/Wolfmanlq/p/6036019.html
二.一個切面類的demo
package springbootDemo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author jiangfeng 2018/7/17 14:57
* 切面類的demo 參考:https://www.cnblogs.com/liuruowang/p/5711563.html
*
* Spring中的AOP代理還是離不開Spring的IOC容器,代理的生成,管理及其依賴關係都是由IOC容器負責,Spring默認使用JDK動態代理,在需要代理類而不是代理接口的時候,
* Spring會自動切換爲使用CGLIB代理,不過現在的項目都是面向接口編程,所以JDK動態代理相對來說用的還是多一些。
*/
@Component
@Aspect
public class SpringOperator {
// 切面公式: 表示server包下所有類所有方法都加
@Pointcut("execution(* springbootDemo.service..*.*(..))")
public void pointCut(){}
// joinPoint (連接點):程序執行過程中明確的點,一般是方法的調用. 獲取執行的環境
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint){
System.out.println("AOP Before ..."+joinPoint.toString());
}
@After("pointCut()")
public void doAfter(JoinPoint joinPoint){
System.out.println("AOP After ..."+joinPoint.toString());
}
@AfterReturning(pointcut="pointCut()",returning="returnVal")
public void afterReturn(JoinPoint joinPoint,Object returnVal){
System.out.println("AOP AfterReturning Advice:"+joinPoint.toString()+"returnval" + returnVal);
}
@AfterThrowing(pointcut="pointCut()",throwing="error")
public void afterThrowing(JoinPoint joinPoint,Throwable error){
System.out.println("AOP AfterThrowing ..." +joinPoint.toString()+"error: "+ error);
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint pjp){
System.out.println("AOP Aronud before...");
try {
Object returnval = pjp.proceed();
System.out.println("AOP Aronud After...");
return returnval;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
}
三. 開發步驟:
1.新增一個切面類
springbootDemo.aop.SpringOperator,
並在類上加上註解:
@Component // 標識spring組件
@Aspect //標識切面類
2.在類里加入切面公式:
// 切面公式: 表示server包下所有類所有方法都加
@Pointcut("execution(* springbootDemo.service..*.*(..))")
public void pointCut(){}
3.各種切面方法,加註解:before,after,afterReturning,afterThrowing,around
四.相關知識點:
(1)Aspect(切面):通常是一個類,裏面可以定義切入點和通知
(2)JointPoint(連接點):程序執行過程中明確的點,一般是方法的調用
(3)Advice(通知):AOP在特定的切入點上執行的增強處理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入點):就是帶有通知的連接點,在程序中主要體現爲書寫切入點表達式
(5)AOP代理:AOP框架創建的對象,代理就是目標對象的加強。Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基於接口,後者基於子類
(6) execution 切面公式
'*' 匹配任意字符,但只能匹配一個元素
'..' 匹配任意字符,可以匹配任意多個元素,表示類時,必須和*聯合使用
'+' 必須跟在類名後面,如Horseman+,表示類本身和繼承或擴展指定類的所有類
Spring中的AOP代理還是離不開Spring的IOC容器,代理的生成,管理及其依賴關係都是由IOC容器負責,Spring默認使用JDK動態代理,在需要代理類而不是代理接口的時候,
Spring會自動切換爲使用CGLIB代理,不過現在的項目都是面向接口編程,所以JDK動態代理相對來說用的還是多一些。
(7) 執行順序:
AOP Aronud before...
AOP Before ...execution(Tag springbootDemo.service.TagService.getTagById(Long))
2018-07-17 16:16:10.411 INFO 15180 --- [nio-8088-exec-4] springbootDemo.service.TagService
AOP Aronud After...
AOP After ...execution(Tag springbootDemo.service.TagService.getTagById(Long))
AOP AfterReturning
注意:
around 時,如果原方法有返回值時,必須返回.否則原方法返回值將被吞
參考:https://www.cnblogs.com/liuruowang/p/5711563.html