Spring(三):注解式AOP的使用

  Spring 支持 AspectJ的注解式切面编程。AOP可以让一组类共享相同的行为。

注解

  1. 使用@Aspect声明一个切面。
  2. 使用@After,@Before,@Around定义建言(Advice),可以直接拦截规则(切点)作为参数。
  3. 其中**@After,@Before,@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After,@Before,@Around**的参数中调用。
  4. 其中符合条件的每一个被拦截处为连接点(JoinPoint)。

示例

  1. 编写拦截规则的注解
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.aop;

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Action {
    String name();
    }
  2. 编写使用注解的被拦截的类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.aop;

    import org.springframework.stereotype.Service;

    @Service
    public class DemoAnnotationService {
    @Action(name="注解释拦截的add操作")
    public void add() {
    System.out.println("DemoAnnotationService ---");

    }
    }
  3. 编写使用方法规则的被拦截的类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.aop;

    import org.springframework.stereotype.Service;

    @Service
    public class DemoMethodService {

    public void add() {
    System.out.println("DemoMethodService ---");
    }

    }
  4. 编写切点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package com.aop;

    import java.lang.reflect.Method;

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;

    @Aspect //声明一个切面
    @Component //成为spring容器中的一个Bean
    public class LogAspect {

    @Pointcut("@annotation(com.aop.Action)")//声明切点
    public void annotationPointCut() {};

    @After("annotationPointCut()") //声明建言,并使用@Pointcut定义切点
    public void after(JoinPoint joinPoint) {
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    Action action = method.getAnnotation(Action.class);
    System.out.println("注解式拦截,在方法执行之后拦截: " + action.name());//通过反射获取注解上的属性
    }

    @Before("execution(* com.aop.DemoMethodService.*(..))")
    public void before(JoinPoint joinPoint) {
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    System.out.println("方法规则式拦截,方法执行之前拦截:" + method.getName());
    }

    }
  5. 编写配置类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.aop;

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;

    @Configuration
    @ComponentScan("com.aop")
    @EnableAspectJAutoProxy//开启spring对AspectJ的支持
    public class AopConfig {

    }

  6. 运行测试
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package com.aop;

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;

    public class AopMain {

    public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);

    DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
    DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);

    demoAnnotationService.add();
    demoMethodService.add();

    context.close();
    }
    }
  7. 运行结果
    1
    2
    3
    4
    DemoAnnotationService ---
    注解式拦截,在方法执行之后拦截: 注解释拦截的add操作
    方法规则式拦截,方法执行之前拦截:add
    DemoMethodService ---
作者

光星

发布于

2018-02-27

更新于

2022-06-17

许可协议

评论