洞察探索如何利用兼容微信生态的小程序容器,实现跨平台开发,助力金融和车联网行业的数字化转型。
653
2023-05-21
Spring AOP注解案例及基本原理详解
切面:Aspect
切面=切入点+通知。在老的spring版本中通常用xml配置,现在通常是一个类带上@Aspect注解。切面负责将 横切逻辑(通知) 编织 到指定的连接点中。
目标对象:Target
将要被增强的对象。
连接点:JoinPoint
切入点:PointCut
需要执行拦截的方法,也就是具体实施了横切逻辑的方法。切入点的规则在spring中通过AspectJ pointcut expression language来描述。
切入点与连接点的区别:连接点是所有可以被"切"的点;切入点是真正要切的点。
通知:Advice
针对切入点的横切逻辑,包含“around”、“before”和“after”等不同类型的通知。
通知的作用点如其命名:
before:在切入点之前执行
after:在切入点之后执行
around:在切入点拦截方法,自定义前后,更灵活
还有一些异常处理的通知,这里不一一举例
织入:Weaving
将切面和目标对象连接起来,创建代理对象的过程。spring中用的是动态代理。假如目标对象有接口,使用jdk动态代理;否则使用cglib动态代理。
说了这么多概念,看看代码实现可能会使读者理解的更深刻一些,这里简单写一个通过注解增强方法的AOP-Demo。
首先是切面类:
package com.example.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author Fcb
* @date 2020/6/20
* @description 切面类=切入点+通知
*/
@Aspect
@Component
public class LogAspect {
//这个方法定义了切入点
@Pointcut("@annotation(com.example.demo.aop.anno.MyLog)")
public void pointCut() {}
//这个方法定义了具体的通知
@After("pointCut()")
public void recordRequestParam(JoinPoint joinPoint) {
for (Object s : joinPoint.getArgs()) {
//打印所有参数,实际中就是记录日志了
System.out.println("after advice : " + s);
EWGxuViYOp }
}
//这个方法定义了具体的通知
@EWGxuViYOpBefore("pointCut()")
public void startRecord(JoinPoint joinPoint) {
for (Object s : joinPoint.getArgs()) {
//打印所有参数
System.out.println("before advice : " + s);
}
}
//这个方法定义了具体的通知
@Around("pointCut()")
public Object arEWGxuViYOpoundRecord(ProceedingJoinPoint pjp) throws Throwable {
for (Object s : pjp.getArgs()) {
//打印所有参数
System.out.println("around advice : " + s);
}
return pjp.proceed();
}
}
注解:
package com.example.demo.aop.anno;
import java.lang.annotation.*;
/**
* @author Fcb
* @date 2020/6/20
* @description
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyLog {
}
目标类:
package com.example.demo.aop.target;
import com.example.demo.aop.anno.MyLog;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Fcb
* @date 2020/6/20
* @description
*/
@RestController
public class MockController {
@RequestMapping("/hello")
@MyLog
public String helloAop(@RequestParam String key) {
System.out.println("do something...");
return "hello world";
}
}
最后是测试类:
package com.example.demo.aop.target;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Fcb
* @date 2020/6/20
* @description
*/
@SpringBootTest
class MockControllerTest {
@Autowired
MockController mockController;
@Test
void helloAop() {
mockController.helloAop("aop");
}
}
控制台结果:
around advice : aop
before advice : aop
do something...
after advice : aop
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~