Spring之创建切点,切面

来源:互联网 发布:淘宝镁光内存条 编辑:程序博客网 时间:2024/05/18 01:06

Spring之编写切点,切面

为了阐述Spring中的切面,我们需要有个主题来定义切面的切点。为此,我们定义一个Performace接口:

`    package concert;    public interface Performance {        pubic void perform();    }`

Performace可以代表任何类型的现场表演,如舞台剧,电影或音乐会。现在来展示一个切点表达式,这个表达式能够设置当perform()方法执行时触发的通知的调用。

`    excution(* concert.Performance.perform(..))`

excution()表示在方法执行时触发,*代表不关心方法的返回值,concert.Performance是所属的类,perform()是方法,里面的..表示使用任意参数。

现在假设我们的切点仅匹配concert包,我们还可以用within()指示器来限制匹配。

`    excution(* concert.Performance.perform(..))        && within(concert.*)`

还可以使用 ‘||’表示或关系,’!’表示非操作。

还有一种要介绍的指示器是bean()指示器,它允许我们在切点表达式中使用bean的id来标识bean。

`    excution(* concert.Performance.perform(..))        and bean('woodstock')`

在这里,我们希望在执行Performance的perform()方法时应用通知,但限定的bean的ID为woodstock.


使用注解创建切面

一场演出没有观众那就不能称之为演出了。观众是非常重要的,但是对演出本身的功能来讲,它并不是核心,这是一个单独的关注点。因此,将观众定义为一个切面,并将其应用到演出上就是较为明智的做法。

`    package concert;    @Aspect    public class Audience {        @Before("excution(** concert.Performance.perform(..))") //表演之前        public void silenceCellPhone() {            System.out.println("Silence cell phones");        }        @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");        }    }`

使用了@AspectJ注解表明Audience不仅仅是一个POJO,还是一个切面。

Spring使用的@AspectJ注解有@After,@AfterReturning,@AfterThrowing,@Around,@Before.

我们可以看出这3个切点表达式是一样的,相同的表达式重复了3遍可不是什么好的事情。如果我们只定义这个切点一次,然后每次需要它的时候引用,这就很好了。

幸好,我们可以这样做,@Poingcut注解能够在一个@AspectJ切面内定义可重用的切点。

`    package concert;    @Aspect    public class Audience {        @Pointcut("excution(** concert.Performance.perform(..))")        public void performance() {}        @Before("performance()") //表演之前        public void silenceCellPhone() {            System.out.println("Silence cell phones");        }        @AfterReturning("performance()") //表演之后         public void applause() {            System.out.println("Clap, Clap ,Clap!!!");        }        @AfterThrowing("performance()") //表演失败之后        public void demandRefund() {            System.out.println("Demanding a refund");        }    }`

performance()的实际内容不重要,在这里他实际上是空的,其实该方法本身只是一个标识,供@Pointcut注解依附。

像其他的java类一样,Audience只是一个java类,只不过他在通过注解表明会作为切面是用而已。
要注意的是,我们若简单的将它声明为一个bean

`       @Bean    public Audience audience() {        return new Audience();    }`

它只会是Spring容器中的一个bean,即便使用了AspectJ注解,但他并不会被视为切面,这些注解不会被解析,也不会创建将其转换为切面的代理。

所以如果你使用JavaConfig的话,可以在配置类的类级别上通过使用@EnableAspecJ-AutoProxy注解启用自动代理功能。

假如在Spring中使用XML来装配,那么需要在

原创粉丝点击