一.什么是切面编程
切面编程(Aspect Oriented Programming,AOP)
如图,这个验证用户这个子流程就成了一个条线,也可以理解成一个切面,aspect的意思就是方面.实现方式有cglib的动态代理,和jdk静态代理.
二.一个切面类的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
*
* 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 时,如果原方法有返回值时,必须返回.否则原方法返回值将被吞