注解+AOP增强执行

728 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前面我们说过如何定义一个注解,如果需要可以回看自己写一个注解,那今天来升级一下,注解加AOP,实现增强逻辑, 

首先定义一个注解MyAnnoTest,注解内有一个参数value用来接收请求方法可能给上的注释,

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnoTest {   
 String value();
}

准备工作完成接着我们定义一个切面MyAspectFirst 该切面类上有三个主角,@Aspect表示它是一个切面类,@Configuration表示它是一个配置,纳入spring管理,@Order(0)表示切面的顺序。 注解后的数字越小,所在切面类越先执行,接着我们在切面类声明一个切入点,这里我声明有注解MyAnnoTest的进入切面,

@Pointcut("@annotation(com.xxx.myAopDemo.annotation.MyAnnoTest)")
public void myTestPoinCut() {}

我们看下pointcut, 此例表示包含MyAnnoTest注解的方法会进入切面(会织入advice),切点分为execution方式和annotation方式。 例:@Pointcut("execution(public * com.example.demo.UserController.*(..))")即可以用路径表达式指定哪些类织入切面,或者本例的指定被哪些注解修饰的代码织入切面 如果想要spring提供的注解也进入我们的切面,例:@GetMapping 在pointcut参数里是org.springframework.web.bind.annotation.GetMapping,

这里注意:

例:execution(* com.example.controller..*.*(..)))* 详解:
1.第一个 * 号的位置:表示返回值类型,* 表示所有类型      
2.包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,本例中指 com.example.controller包、子包下所有类的方法     
3.第二个 * 号的位置:表示类名,* 表示所有类      
4.*(..):这个星号表示方法名,* 表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

我们定义一个请求方法,方法我们请求的时候可以达到我们测试的目的,当我们的请求包含该注解的方法时你会发现时如果存在@Before然后会去执行@Before对应的方法就相当于方法执行逻辑前会去执行下AOP里的方法,

@Before(value = "myTestPoinCut() && @annotation(myAnnoTest)")
public void checkBefore(JoinPoint joinPoint, MyAnnoTest myAnnoTest){  
  System.out.println("我是第一个执行该方法的切面");
}

里面的参数joinPoint表示连接点,@Around表示环绕通知,在流程开始前和流程结束之后这之间都在它里面

/** *@Around 环绕通知 * @param joinPoint */
@Around("myTestPoinCut()")
public void checkAround(ProceedingJoinPoint joinPoint){    
//joinPoint.getArgs();    
System.out.println("我入了Around");   
 try {        joinPoint.proceed();    } 
catch (Throwable e) {        e.printStackTrace();    }    
System.out.println("我出了Around");}

最后结果:

我入了Around
我是第一个执行该方法的切面
66666
我出了Around

看起来可能很简单,没事动动手,觉得还是可以练练的