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

star2017 1年前 ⋅ 662 阅读

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

注解

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

示例

  1. 编写拦截规则的注解

     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. 编写使用注解的被拦截的类

     package com.aop;
    
     import org.springframework.stereotype.Service;
    
     @Service
     public class DemoAnnotationService {
         @Action(name="注解释拦截的add操作")
         public void add() {
             System.out.println("DemoAnnotationService ---");
    
         }
     }
    
  3. 编写使用方法规则的被拦截的类

     package com.aop;
    
     import org.springframework.stereotype.Service;
    
     @Service
     public class DemoMethodService {
    
         public void add() {
             System.out.println("DemoMethodService ---");
         }
    
     }
    
  4. 编写切点

     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. 编写配置类

     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. 运行测试

     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. 运行结果

     DemoAnnotationService ---
     注解式拦截,在方法执行之后拦截: 注解释拦截的add操作
     方法规则式拦截,方法执行之前拦截:add
     DemoMethodService ---
    
更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: