Spring AOP (二)

在Spring实战一书中看到Spring提供了4中类型的AOP支持:

1. 基于代理的经典Spring AOP;

2. POJO切面;

3. @AspectJ注解驱动的切面;

4. 注入式AspectJ切面(适用于Spring各版本);

上一节的例子就是POJO切面的方式实现Spring AOP.

@AspectJ创建切面

1. @AspectJ定义切面,这里注意一点,@Before和@After里面放的是切点

package aop.kind3;

import org.aspectj.lang.annotation.*;

@Aspect
public class Audience {

    @Pointcut("execution(* aop.kind3.Performance.perform(..))")
    public void performance() {} // 定义切点

    @Before("performance()")
    public void takeSeats() {
        // 节目开始之前
        System.out.println("Taking seats");
    }

    @Before("performance()")
    public void turnOffCellPhones() {
        // 节目开始之前
        System.out.println("Slicening cell phone");
    }

    @AfterReturning("performance()")
    public void applaud() {
        // 节目成功结束之后
        System.out.println("CLAP CLAP CLAP");
    }

    @AfterThrowing("performance()")
    public void demandRefund() {
        // 节目表演失败之后
        System.out.println("Demanding a refund");
    }
}

Audience类不仅仅是一个pojo(plain ordinary java object),还是一个切面,我们知道一个切面需要有两部分组成,切点和通知,切点定义了在何处,通知定义了在何时和做什么,这样就完成了切面的定义。

注解通知
@After通知方法会在目标方法返回或抛出异常后调用
@AfterReturning通知方法会在目标方法返回后调用
@AfterThrowing通知方法会在目标方法抛出异常后调用
@Around通知方法会将目标方法封装起来
@Before通知方法会在目标方法调用之前执行

除了注解和没有实际操作的performance()方法,Audience类依然是一个POJO,可以像其他类一样使用,单元测试。Audience只是一个Java类,只不过它通过注解表明会作为切面使用而已。

基于xml的方式使用

在XML中,通过Spring的aop命名空间启用AspectJ自动代理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <!-- 添加<aop:aspectj-autoproxy />实现注解切面 -->
    <aop:aspectj-autoproxy />
    <bean id="drama" class="aop.kind3.Drama" />
    <bean id="audience" class="aop.kind3.Audience" />
</beans>

创建环绕通知

环绕通知编写的逻辑将被通知的目标方法完全包装起来。实际上就像在一个通知方法中同时编写前置通
知和后置通知。实现:重写Audience切面。

package aop.kind3.around;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class Audience {

    @Pointcut("execution(* aop.kind3.Performance.perform(..))")
    public void performance() {} // 定义切点

    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint jp) {

        try {
            System.out.println("Slicening cell phone");
            System.out.println("Taking seats");
            jp.proceed();
            System.out.println("CLAP CLAP CLAP");
        }catch (Throwable e){
            System.out.println("Demanding a refund");
        }

    }
}

知识点:

1. @Around表示环绕注解,watchPerformance()方法会作为performance()切点的环绕通知。

2. ProceedingJoinPoin jp作为参数,这个对象是必须要有的,因为你要在通知中通过jp来调用被通知的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值