spring AOP概念及应用场景
概念
面向切面编程,通过预编译和运行期间动态代理实现在不修改源代码的情况下给程序动态统一添加功能的技术
思想就是把很多类中对象中横切问题点,从业务逻辑中分离出来,达到解耦的目的,增加代码的重用性,提高开发效率
应用场景
日志记录,异常处理,权限校验,缓存梳理,
事物处理,数据持久化,效率检查,内容分发
主要概念理解
aspect
切面,切面有切点和通知组成,即包括横切逻辑的定义和连接点的定义
pointcut
切点,每个类都拥有多个连接点,可以理解是连接点的集合
joinpoint
连接点,程序执行的某个特殊位置,如某个方法调用前后
weaving
织入,将增强添加到目标类的具体连接点的过程
advice
通知,是织入到目标类连接点上的一段代码,就是增强到什么地方?什么内容
target
目标对象,通知织入的目标类
aop proxy
代理对象,即增强后产生的对象
实现
1. 定义一个切面类Aspect
在声明的类,增加@Component @Aspect注解,springboot中引入是spring-boot-stater-aop依赖包
2. 定义切点Pointcut
定义切点,并声明切点在哪些地方执行
采用@Pointcut 注解 如@Pointcut (public * com.xx.xx.*.*(..) )
规则:修饰符 + 返回类型 + 包.类 + 方法 + 参数 ,* 表示不限,.. 表示参数不限
3. 定义Advice通知
五种注解类型 @Before @AfterReturning @AfterThrowing @Around @After
比如 @Before("xx()") xx为第二部定义的切点
示例
@Aspect @Component public class LoggerAspect { private final Logger logger = LoggerFactory.getLogger(LoggerAspect.class); @Pointcut(value = "execution(* com.choc.boht.controller.*.*(..))") public void myPointCut() { } @Around("myPointCut()") public Object applicationLogger(ProceedingJoinPoint pjp) throws Throwable { logger.info("乌拉1~"); String medthodName = pjp.getSignature().getName(); String className = pjp.getTarget().getClass().toString(); Object[] args = pjp.getArgs(); ObjectMapper mapper = new ObjectMapper(); Object obj = pjp.proceed(); String requestData = mapper.writeValueAsString(args); String reponseData = mapper.writeValueAsString(obj); logger.info("medthodName:{},className:{},requestData:{},reponseData:{},args:{}",medthodName,className,requestData,reponseData,args); return pjp.proceed(); } }