拦截器类型

顾名思义,拦截器有以下类型:

  • @Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;
  • @After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;
  • @AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;
  • @AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;
  • @Around:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。

注解

首先复习以下注解,注解有以下元注解,也就是 Java 已经定义好的,我们使用就可以了

@Target

最常用的元注解是@Target。使用@Target可以定义Annotation能够被应用于源码的哪些位置:

  • 类或接口:ElementType.TYPE
  • 字段:ElementType.FIELD
  • 方法:ElementType.METHOD
  • 构造方法:ElementType.CONSTRUCTOR
  • 方法参数:ElementType.PARAMETER

    @Retention

    另一个重要的元注解@Retention定义了Annotation的生命周期:

  • 仅编译期:RetentionPolicy.SOURCE

  • 仅class文件:RetentionPolicy.CLASS
  • 运行期:RetentionPolicy.RUNTIME

实现过程

接下来,我们实现以下如何通过注解来装配 AOP
新建一个 security 接口

  1. import java.lang.annotation.Retention;
  2. import java.lang.annotation.Target;
  3. import static java.lang.annotation.ElementType.METHOD;
  4. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  5. @Target(METHOD)
  6. @Retention(RUNTIME)
  7. public @interface Security {}

接着我们实现 切面文件, 并实现拦截器

  1. @Component
  2. @Aspect
  3. public class SecurityCheckAspect {
  4. @Before("@annotation(Security)")
  5. public void init(){
  6. System.out.println("init security testing ");
  7. }
  8. }

最后,我们把拦截器装到相应的方法上面

  1. @Component
  2. public class UserService {
  3. ...
  4. @Security()
  5. public User Register(){
  6. System.out.println("Register User");
  7. System.out.println("register successful");
  8. return new User();
  9. }
  10. }

最后运行,可以看到如下输出

  1. init security testing
  2. Register User
  3. register successful

这样就实现了一个最简单的注解装配 AOP 的例子