美文网首页
Spring AOP

Spring AOP

作者: TheMrBigHead | 来源:发表于2018-09-07 06:51 被阅读0次

    Spring AOP

    一、面向切面编程

    1. AOP术语
    image.png
    1.1 ADVICE(增强)
    在aop中,aspect的职责(功能)被称为advice。它定义了一个aspect在什么时间应该做什么事情。
    

    Spring提供了以下几种advice:

    1. Before 在目标的方法调用之前调用advice的功能
    2. After 在目标方法调用之后调用advice的功能
    3. After-returning 在目标方法成功调用完成后,调用advice的功能
    4. After-throwing 在目标方法抛出异常后,调用advice的功能
    5. Around 环绕增强,在目标方法之前和之后都来调用advice的功能
    1.2 JOIN POINTS(连接点)
    连接点是应用程序执行中可以插入切面的点
    
    1.3 POINTCUTS(切点)
    切点定义了增强在什么地方产生作用。
    

    切点匹配一个或多个应该被注入增强的连接点的位置。

    1.4 ASPECTS(切面)
    切面是切点和增强的组合,它定义了增强应该在什么时间、什么地点去做什么事情
    
    1.5 INTRODUCTIONS
     Introductions允许你向一个已经存在的类添加新的属性或方法
    
    1.6 WEAVING(织入)
    织入就是讲切面应用到目标对象上以创造一个新的代理对象的过程
    

    织入发生在目标对象声明周期的几个时间点:

    1. 编译时
    2. 类加载时
    3. 运行时 (Spring在这个阶段织入切面)
    2. Spring对AOP的支持

    Spring’s support for AOP comes in four styles:

    1. Classic Spring proxy-based AOP
    2. Pure-POJO aspects
    3. @AspectJ annotation-driven aspects
    4. Injected AspectJ aspects (available in all versions of Spring)

    Spring AOP框架的一些关键点:

    1. Spring增强是试用JAVA写的,是标准的java类

    2. Spring是在运行时(runtime)增强目标对象的


      image.png
    3. Spring仅仅支持方法级别的连接点(原因是Spring AOP是基于动态代理的)

    2.1 在切点中选择连接点
    image.png
    2.1.1 写一个切点
    package concert;
    public interface Performance {
      public void perform();
    }
    
    image.png image.png

    && and
    || or
    ! not

    2.1.2 在切点中选取Bean
    选取ID为woodstock的bean 选取ID不为woodstock的bean
    3. 创建被注解的切面
    3.1 定义切面
    package concert;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    @Aspect
    public class Audience {
      @Before("execution(** concert.Performance.perform(..))")
      public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
      }
    
      @Before("execution(** concert.Performance.perform(..))")
      public void takeSeats() {
        System.out.println("Taking seats");
      }
    
       @AfterReturning("execution(** concert.Performance.perform(..))")
       public void applause() {
         System.out.println("CLAP CLAP CLAP!!!");
      }
    
      @AfterThrowing("execution(** concert.Performance.perform(..))")
       public void demandRefund() {
         System.out.println("Demanding a refund");
      }
    }
    

    注解@Aspect表明当前类是一个切面

    image.png

    使用@Pointcut注解来定义一个可以重用的切点

    package concert;
    
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class Audience {
    
      @Pointcut("execution(** concert.Performance.perform(..))")
      public void performance() {}
    
      @Before("performance()")
      public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
      }
    
      @Before("performance()")
      public void takeSeats() {
        System.out.println("Taking seats");
      }
    
      @AfterReturning("performance()")
      public void applause() {
        System.out.println("CLAP CLAP CLAP!!!");
      }
    
      @AfterThrowing("performance()")
      public void demandRefund() {
        System.out.println("Demanding a refund");
      }
    }
    

    配置切面自动代理:

    @Configuration
    @EnableAspectJAutoProxy   // Enable AspectJ auto-proxying
    @ComponentScan
    public class ConcertConfig {
        @Bean
        public Audience audience() {
            return new Audience();
        }
    }
    

    <aop:aspectj-autoproxy>
    
    3.2 创建一个Around Advice(环绕增强)
      @Around("performance()")
      public void watchPerformance(ProceedingJoinPoint jp) {
        try {
          System.out.println("Silencing cell phones");
          System.out.println("Taking seats");
          jp.proceed();
          System.out.println("CLAP CLAP CLAP!!!");
        } catch (Throwable e) {
          System.out.println("Demanding a refund");
        }
     }
    

    ProceedingJoinPoint

    3.3 处理Advice里的参数
    package soundsystem;
    import java.util.HashMap;
    import java.util.Map;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    @Aspect
    public class TrackCounter {
      private Map<Integer, Integer> trackCounts =
          new HashMap<Integer, Integer>();
      @Pointcut(
         "execution(* soundsystem.CompactDisc.playTrack(int)) " +
         "&& args(trackNumber)")
      public void trackPlayed(int trackNumber) {}
    
      @Before("trackPlayed(trackNumber)")
      public void countTrack(int trackNumber) {
        int currentCount = getPlayCount(trackNumber);
        trackCounts.put(trackNumber, currentCount + 1);
      }
      public int getPlayCount(int trackNumber) {
        return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0;
      }
     }
    
    image.png
    3.4 Annotating introductions
    introductions向bean添加新的方法
    
    image.png
    package concert;
    public interface Encoreable {
        void performEncore();
    }
    
    package concert;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.DeclareParents;
    
    @Aspect
    public class EncoreableIntroducer {
      @DeclareParents(value="concert.Performance+",
                      defaultImpl=DefaultEncoreable.class)
      public static Encoreable encoreable;
    }
    

    @DeclareParents注解由以下三个部分组成:

    1. value 表明有几种Bean需要引入这个interface,在例子中的是Performance本身及其所有子类都需要(“+”表示自己及所有子类)
    2. defaultImpl 属性指明了一个默认的introduction interface的实现类
    3. static 被@DeclareParents注解的属性是static的,表明是一个被introduction的接口
    4. 在xml配置文件里声明切面
    image.png
    image.png
      <!--启用自动代理-->
      <aop:aspectj-autoproxy>
    
    image.png image.png image.png image.png image.png

    相关文章

      网友评论

          本文标题:Spring AOP

          本文链接:https://www.haomeiwen.com/subject/fvuxgftx.html