• SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-005-定义切面使用@Aspect、@EnableAspectJAutoProxy、<aop:aspectj-autoproxy>


    一、

    假设有如下情况,有一个演凑者和一批观众,要实现在演凑者的演凑方法前织入观众的"坐下"、"关手机方法",在演凑结束后,如果成功,则织入观众"鼓掌",演凑出错则观众要求"回水"

    基本的类如下:

    1.

    package com.springinaction.springidol;
    
    public interface Instrument {
      public void play();
    }

    2.

    1 package com.springinaction.springidol;
    2 
    3 public class Guitar implements Instrument {
    4   public void play() {
    5     System.out.println("Strum strum strum");
    6   }
    7 }

    3.

    package com.springinaction.springidol;
    
    public interface Performer {
      void perform() throws PerformanceException;
    }

    4.

     1 package com.springinaction.springidol;
     2 
     3 public class Instrumentalist implements Performer {
     4   public void perform() throws PerformanceException {
     5     instrument.play();
     6   }
     7 
     8   private Instrument instrument;
     9 
    10   public void setInstrument(Instrument instrument) {
    11     this.instrument = instrument;
    12   }
    13 
    14   public Instrument getInstrument() {
    15     return instrument;
    16   }
    17 }

     

    二、

    可以定义的advice

    Spring的切面是一个pojo

    1.使用@Aspect定义切面类

    (1)不同的方法可以用不同的pointcut

     1 package concert;
     2 import org.aspectj.lang.annotation.AfterReturning;
     3 import org.aspectj.lang.annotation.AfterThrowing;
     4 import org.aspectj.lang.annotation.Aspect;
     5 import org.aspectj.lang.annotation.Before;
     6 @Aspect
     7 public class Audience {
     8     @Before("execution(** concert.Performance.perform(..))")
     9     public void silenceCellPhones() {
    10         System.out.println("Silencing cell phones");
    11     }
    12     @Before("execution(** concert.Performance.perform(..))")
    13     public void takeSeats() {
    14         System.out.println("Taking seats");
    15     }
    16     @AfterReturning("execution(** concert.Performance.perform(..))")
    17     public void applause() {
    18         System.out.println("CLAP CLAP CLAP!!!");
    19     }
    20     @AfterThrowing("execution(** concert.Performance.perform(..))")
    21     public void demandRefund() {
    22         System.out.println("Demanding a refund");
    23     }
    24 }

    (2)定义一个公共的pointcut,其对应的方法名就是id

     1 package com.springinaction.springidol;
     2 
     3 import org.aspectj.lang.annotation.AfterReturning;
     4 import org.aspectj.lang.annotation.AfterThrowing;
     5 import org.aspectj.lang.annotation.Aspect;
     6 import org.aspectj.lang.annotation.Before;
     7 import org.aspectj.lang.annotation.Pointcut;
     8 
     9 @Aspect
    10 public class Audience {
    11   @Pointcut(
    12         "execution(* com.springinaction.springidol.Performer.perform(..))")
    13   public void performance() { //<co id="co_definePointcut"/>
    14   }
    15 
    16   @Before("performance()")
    17   public void takeSeats() { //<co id="co_takeSeatsBefore"/>
    18     System.out.println("The audience is taking their seats.");
    19   }
    20 
    21   @Before("performance()")
    22   public void turnOffCellPhones() { //<co id="co_turnOffCellPhonesBefore"/>
    23     System.out.println("The audience is turning off their cellphones");
    24   }
    25 
    26   @AfterReturning("performance()")
    27   public void applaud() { //<co id="co_applaudAfter"/>
    28     System.out.println("CLAP CLAP CLAP CLAP CLAP");
    29   }
    30 
    31   @AfterThrowing("performance()")
    32   public void demandRefund() { //<co id="co_demandRefundAfterException"/>
    33     System.out.println("Boo! We want our money back!");
    34   }
    35 }

    2.把切面交给Spring容器

    (1)在java配置文件中,使用@EnableAspectJAutoProxy

     1 package concert;
     2 import org.springframework.context.annotation.Bean;
     3 import org.springframework.context.annotation.ComponentScan;
     4 import org.springframework.context.annotation.Configuration;
     5 import org.springframework.context.annotation.EnableAspectJAutoProxy;
     6 @Configuration
     7 @EnableAspectJAutoProxy
     8 @ComponentScan
     9 public class ConcertConfig {
    10     @Bean
    11     public Audience audience() {
    12         return new Audience();
    13     }
    14 }

    (2)在xml使用<aop:aspectj-autoproxy>

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!--<start id="preamble" />--> 
     3 <beans xmlns="http://www.springframework.org/schema/beans"
     4  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     5  xmlns:aop="http://www.springframework.org/schema/aop"
     6  xsi:schemaLocation="http://www.springframework.org/schema/beans 
     7      http://www.springframework.org/schema/beans/spring-beans.xsd
     8      http://www.springframework.org/schema/aop
     9      http://www.springframework.org/schema/aop/spring-aop.xsd">
    10 <!--<end id="preamble" />-->
    11 
    12   <bean id="eddie"
    13       class="com.springinaction.springidol.Instrumentalist">
    14     <property name="instrument">
    15       <bean class="com.springinaction.springidol.Guitar" />
    16     </property>
    17   </bean>
    18 
    19   <!--<start id="audience_bean" />--> 
    20   <bean id="audience" 
    21       class="com.springinaction.springidol.Audience" /> 
    22   <!--<end id="audience_bean" />-->
    23 
    24   <!--<start id="contestant_introducer" />--> 
    25   <bean class="com.springinaction.springidol.ContestantIntroducer" />
    26   <!--<end id="contestant_introducer" />-->
    27 
    28   <!--<start id="aspectj_autoproxy" />--> 
    29     <aop:aspectj-autoproxy />
    30   <!--<end id="aspectj_autoproxy" />-->
    31 
    32 </beans>

    3.测试

    package com.springinaction.springidol;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("spring-idol.xml")
    public class AspectTest {
      @Autowired
      ApplicationContext context;
    
      @Test
      public void audienceShouldApplaud() throws Exception {
        Performer eddie = (Performer) context.getBean("eddie");
        eddie.perform();
      }
    
      @Test
      public void eddieShouldBeAContestant() {
        Contestant eddie = (Contestant) context.getBean("eddie");
        eddie.receiveAward();
      }
    }

    audienceShouldApplaud的测试结果:

    The audience is taking their seats.
    The audience is turning off their cellphones
    Strum strum strum
    CLAP CLAP CLAP CLAP CLAP
  • 相关阅读:
    在Ubuntu11.10中安装OpenCV2.3.1的详细步骤
    基于二元语法模型的中文分词
    相似图片搜索的原理
    基于GPU的KMeans聚类算法
    Windows下Eclipse和PyDev搭建完美Python开发环境
    Ubuntu 11.10+win7双系统启动项管理及配置方法
    主题爬虫
    vue定义全局过滤器
    element elimage 放多张图片,显示大图
    element UI的form 禁止浏览器自动填充用户名或密码
  • 原文地址:https://www.cnblogs.com/shamgod/p/5239512.html
Copyright © 2020-2023  润新知