Spring之AOP

AOP,也叫面向切面编程,也就是一种在系统运行时动态添加代码的方式。

说通俗点,就是规定某些方法在执行前需要做些什么,执行完了之后做些什么。

先介绍几个概念

Joinpoint 连接点   类里面可以被增强的方法就是连接点 eg:想修改某个方法的功能,那么该方法就是连接点
Pointcut 切入点     对Joinpoint进行拦截的定义就是切入点 eg:拦截所有的Insert方法,这个就是切入点
Advice 通知   拦截到Joinpoint之后要做的事情就是通知
Aspect 切面   Pointcut 和 Advice 的结合
Target 目标对象    要增强的类就是目标对象

然后介绍几个注解

@Aspect 表明这是一个切面类

@Pointcut 定义切入点
eg: @Pointcut("excution(* org.sang.aop.service.*.*(..))")
第一个*表示方法返回任意值
第二个*表示service包下的任意类
第三个*表示类中的任意方法
括号中的..表示方法参数任意

@Before 前置通知
该方法在目标方法执行之前执行,通过JoinPoint 参数可以取到目标方法的方法名、修饰符等信息

@After 后置通知

@AfterReturning 返回通知
在该方法中可以获取目标方法的返回值
其中 returning 参数是指返回值的变量名,对应方法的参数
在方法参数中如果result定义为Object 类型,表示目标方法的返回值可以是任意类型

@AfterThrowing 异常通知

@Around 环绕通知
功能最强大的通知,可以实现前置通知、后置通知、异常通知以及返回通知的功能

下面看一个具体的例子:

@Component
@Aspect
public class UserAspect {
    
    @Pointcut("execution(* com.example.yang.service.UserService.*(..))")
    public void pc() {
        
    }
    
    @Before(value="pc()")
    public void before(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println(name + "方法开始执行!");
    }
    
    @After(value="pc()")
    public void after(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println(name+ "方法执行结束!");
    }
    
    @AfterReturning(value="pc()", returning="result")
    public void afterReturning(JoinPoint jp, Object result) {
        String name = jp.getSignature().getName();
        System.out.println(name+"方法的返回值是:"+result);
    }
    
    @AfterThrowing(value="pc()", throwing="e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        String name = jp.getSignature().getName();
        System.out.println(name + "抛出异常了,异常信息是:"+e.getMessage());
    }
    
    @Around("pc()")
    public Object around(ProceedingJoinPoint pjp) {
        String name = pjp.getSignature().getName();
        System.out.println(name+"方法开始执行");
        try {
            Object result = pjp.proceed();
            System.out.println(name+"方法的返回值为:"+result);
            return result;
            
        } catch (Throwable e) {
            System.out.println(name+"方法出现异常");
            return null;
        }finally {
            System.out.println(name+"方法执行结束");
        }
    }
}

使用起来还是挺简单的,就提一下@Around的注意点:

你原本的方法是什么返回值,那么这个around函数的返回值就是什么,

pjp.proceed()虽然会使目标方法继续执行,但是目标方法返回的内容会变成由around方法返回
比如:你的目标方法执行两个操作,一个是输出一句话,一个是return一个字符串
在around方法中虽然执行了pjp.proceed(),只会输出那句话,但是return null

 

posted @ 2019-07-27 19:27  xtu熊大  阅读(217)  评论(0编辑  收藏  举报