Spring AOP 切面与通知【Spring 入门】

时间:2022-10-26 20:28:58
Spring AOP框架提供了一种面向切面编程的方法。之前如果我们要给一个类添加日志功能,记录方法的调用,异常情况,我们需要在类中去写无数的log,这样不仅使得代码混乱,不易维护,也使得代码复用性降低。
现在我们有了AOP,就可以解决这些问题。
从一个现实例子入手,观众去看演唱会,观众在歌手上舞台之前,要入座,歌手开始唱歌,如果唱的好观众会鼓掌,唱的不好,观众会吐槽,唱完之后,观众会离场。观众的这一切行为,都是因歌手而产生,但是歌手却不必关心观众的行为,也不用主动让观众鼓掌,歌手就做好他的唱歌工作就好。在这个例子中,观众就是切面,记录着歌手的行为,并做出相应反应。
下面看代码实例
Singer.java
package com.aop;

import org.springframework.stereotype.Component;

@Component//将歌手类生成bean
public class Singer {

    public void sing(){
        System.out.println("sing");
    }
}
可以看出,歌手类的代码很简洁,他并不需要管其它事情(如主动让观众鼓掌)。

Audience.java
package com.aop;

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

@Aspect//将观众声明为切面
public class Audience {
    //定义切点,不能把本切面中的方法包括进去,不然会循环注入
    @Pointcut("execution( * com.aop.Singer.sing(..))" )
    public void singer(){}//切点表达式

    @Before("singer()")//调用方法前执行的通知
    public void before(){
        System.out.println("before");
    }

    @After("singer()")//调用方法后执行的通知
    public void after(){
        System.out.println("after");
    }

    @AfterReturning("singer()")//调用方法返回后执行的通知
    public void afterReturning(){
        System.out.println("afterReturning");
    }

    @AfterThrowing("singer()")//调用方法抛出异常执行的通知
    public void afterThrowing(){
        System.out.println("afterThrowing");
    }

    @Around("singer()")//环绕通知
    public void around(ProceedingJoinPoint pjp){
        try{
            System.out.println("around-before");
            pjp.proceed();
            System.out.println("around-after");
        }catch (Throwable e){
            e.printStackTrace();
        }
    }
}
观众就是一个切面。观众主动根据歌手执行的方法,做出响应。

配置文件:
package com.aop;

import org.springframework.context.annotation.*;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy//启用AspectJ注解的自动代理
public class Config {
    @Bean//声明Audience bean
    public Audience audience(){
        return new Audience();
    }
}