Spring中AOP注解@Aspect的使用详解
作者:可以简单点
AOP思想
AOP(Aspect Oriented Programming)是一种面向切面的编程思想。面向切面编程是将程序抽象成各个切面,即解剖对象的内部,将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性。AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理、增强处理。
AOP的使用场景
权限认证、日志、事务处理、增强处理
@Aspect的使用以及基本概念
1.切面类 @Aspect: 定义切面类,加上@Aspect、@Component注解
@Aspect @Component //设置注解执行的顺序 @Order(2) public class AnnotationAspectTest
2.切点 @Pointcut
/** * 定义切点,切点为对应controller */ @Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))") public void aopPointCut(){ }
注:execution表达式第一个*表示匹配任意的方法返回值,第二个*表示所有controller包下的类,第三个*表示所有方法,第一个..表示任意参数个数。
3.Advice,在切入点上执行的增强处理,主要有五个注解:
@Before 在切点方法之前执行
@After 在切点方法之后执行
@AfterReturning 切点方法返回后执行
@AfterThrowing 切点方法抛异常执行
@Around 属于环绕增强,能控制切点执行前,执行后
4.JoinPoint :方法中的参数JoinPoint为连接点对象,它可以获取当前切入的方法的参数、代理类等信息,因此可以记录一些信息,验证一些信息等;
5.使用&&、||、!、三种运算符来组合切点表达式,表示与或非的关系;
6.@annotation(annotationType) 匹配指定注解为切入点的方法;
具体代码实现
1.AopController,用于校验aop是否生效:
@Controller @RequestMapping("aop") public class AopController { @RequestMapping("test") @ResponseBody public String aopTest(User user) { // System.out.println(user); System.out.println("aop测试"); return "success"; } @TestAnnotation(flag = false) @RequestMapping("aopAnnotationTest") @ResponseBody public String aopAnnotationTest(User user) { // System.out.println(user); System.out.println("aopAnnotationTest"); return "success"; } }
2.AspectTest,具体的切面类,用于添加横切逻辑,切点使用execution表达式进行匹配
@Aspect @Component //设置注解执行的顺序 @Order(1) public class AspectTest { /** * 定义切点,切点为对应controller */ @Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))") public void aopPointCut(){ } @Before("aopPointCut()") public void testbefor(JoinPoint joinPoint) { illegalParam(joinPoint); System.out.println("执行方法之前执行。。。。。"); } @After("aopPointCut()") public void testAfter(JoinPoint joinPoint) { //illegalParam(joinPoint); System.out.println("执行方法之后执行。。。。。"); } /** *获取请求参数 * @param joinPoint * @return */ private static void illegalParam(JoinPoint joinPoint) { if(joinPoint == null){ return; } boolean flag = false; try{ // 参数值 Object[] args = joinPoint.getArgs(); if (args != null) { for (Object o : args) { System.out.println(o); } } }catch(Exception e){ } } }
3.AnnotationAspectTest类,具体的切面类,用于添加横切逻辑,切点指定注解
@Aspect @Component //设置注解执行的顺序 @Order(2) public class AnnotationAspectTest { /** * 定义切点,切点为添加了注解的方法 */ @Pointcut("@annotation(com.example.zcs.Aop.annotation.TestAnnotation)") public void aopPointCut(){ } @Around("aopPointCut()") public Object Around(ProceedingJoinPoint point) throws Throwable { System.out.println("AnnotationAspectTest Around start "); //获取注解和注解的值 TestAnnotation annotation = getAnnotation(point); if (annotation != null) { boolean flag = annotation.flag(); System.out.println("注解flags的值:" + flag); } //获取参数 Object[] args = point.getArgs(); for (Object arg : args) { System.out.println("arg ==>" + arg); } //去调用被拦截的方法 Object proceed = point.proceed(); return proceed; } //获取注解 public TestAnnotation getAnnotation(ProceedingJoinPoint point) { Signature signature = point.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null){ return method.getAnnotation(TestAnnotation.class); } return null; } }
4.注解类TestAnnotation
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TestAnnotation { boolean flag() default true; }
到此这篇关于Spring中AOP注解@Aspect的使用详解的文章就介绍到这了,更多相关Spring的@Aspect注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!