SpringAOP概念及其使用

什么是AOP

AOP(Aspect Oriented Programming 面向切面编程),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

常用于日志记录,性能统计,安全控制,事务处理,异常处理等等。

定义AOP术语

切面(Aspect):切面是一个关注点的模块化,这个关注点可能是横切多个对象;

连接点(Join Point):连接点是指在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候;

通知(Advice):指在切面的某个特定的连接点上执行的动作。Spring切面可以应用5中通知:

  • 前置通知(Before):在目标方法或者说连接点被调用前执行的通知;
  • 后置通知(After):指在某个连接点完成后执行的通知;
  • 返回通知(After-returning):指在某个连接点成功执行之后执行的通知;
  • 异常通知(After-throwing):指在方法抛出异常后执行的通知;
  • 环绕通知(Around):指包围一个连接点通知,在被通知的方法调用之前和之后执行自定义的方法。

切点(Pointcut):指匹配连接点的断言。通知与一个切入点表达式关联,并在满足这个切入的连接点上运行,例如:当执行某个特定的名称的方法。

引入(Introduction):引入也被称为内部类型声明,声明额外的方法或者某个类型的字段。

目标对象(Target Object):目标对象是被一个或者多个切面所通知的对象。

AOP代理(AOP Proxy):AOP代理是指AOP框架创建的对对象,用来实现切面契约(包括通知方法等功能)

织入(Wearving):指把切面连接到其他应用出程序类型或者对象上,并创建一个被通知的对象。或者说形成代理对象的方法的过程。

Spring对AOP的支持

  1. 基于代理的经典SpringAOP;
  2. 纯POJO切面;
  3. @AspectJ注解驱动的切面;
  4. 注入式AspectJ切面(适用于Spring各版本);

前三种都是SpringAOP实现的变体,SpringAOP构建在动态代理基础之上,因此,Spring对AOP的支持局限于方法的拦截。

切入点表达式

使用SpringAOP

SpringAOP的支持必须呀导入spring-aspects的jar包

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

使用注解定义切面

采用注解的方式定义切面以及通知

    @Aspect
    public class Audience {
        //使用@Pointcut注解声明频繁使用的切入点表达式
        @Pointcut("execution(* com.wqh.concert.Performance.perform(..))")
        public void performance(){}

        @Before("performance()")
        public void silenceCellPhones(){
            System.out.println("Sillencing cell phones");
        }
        @Before("performance()")
        public void takeSeats(){
            System.out.println("Task Seat");
        }
        @AfterReturning("performance()")
        public void applause(){
            System.out.println("CLAP CLAP CLAP");
        }
        @AfterThrowing("performance()")
        public void demandRefund(){
            System.out.println("Demand a Refund");
        }
    }

另外需要在applicationContext.xml也就是spring的配置文件中添加配置:

    <!--启用AspectJ的自动代理-->
    <aop:aspectj-autoproxy/>
    <!--声明bean-->
    <bean class="com.wqh.concert.Audience"/>

在XML中声明切面

定义pojo类,这里只是把上面定义的注解全public class AudienceXML {

public void silenceCellPhones() {
    System.out.println("Sillencing cell phones");
}
public void takeSeats() {
    System.out.println("Task Seat");
}
public void applause() {
    System.out.println("CLAP CLAP CLAP");
}
public void demandRefund() {
    System.out.println("Demand a Refund");
}

applicationContext.xml配置

    <!--声明bean-->
    <bean name="audienceXML" class="com.wqh.concert.AudienceXML"/>
    <aop:config>
        <!--引入bean-->
        <aop:aspect ref="audienceXML">
            <!--定义切点-->
            <aop:pointcut id="perform"
                          expression="execution(* com.wqh.concert.Performance.perform(..))"/>
            <!--定义通知
                method:通知,也就是具体的方法
                pointcut-ref:引用的切点
                pointcut:切点-->
            <aop:before method="silenceCellPhones"
                        pointcut-ref="perform"/>

            <aop:before method="takeSeats" pointcut-ref="perform"/>
            <aop:after-returning method="applause" pointcut-ref="perform"/>

            <aop:after-throwing method="demandRefund"
                                pointcut="execution(* com.wqh.concert.Performance.perform(..))"/>
        </aop:aspect>
    </aop:config>

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页