Spring AOP概念术语

430 阅读2分钟

参考资料:Spring AOP概念术语的通俗理解

Spring AOP术语

  • 通知(Advice)
    • 就是横切时,你要做什么事情。比如权限验证、日志、事务等
  • 连接点(JoinPoint)
    • 就是允许使用通知的地方,比如有个hello方法,允许hello执行前切入,那么hello前的位置就是一个连接点。
  • 切入点(Pointcut)
    • 连接点有很多,那么你想哪个位置切入,那个位置就是切入点。比如:hello方法前后都有连接点,我想在hello前执行通知,那么hello前就是个切入点
  • 切面(Aspect)
    • 切面是切入点+通知,通俗来说,就是在哪个位置(切入点),想做什么事情(通知)
  • 目标(Target)
    • 就是指被通知的对象,比如有个HelloTest类,里面有hello方法。现在要在hello方法前执行通知,HelloTest就是目标类
  • 代理(Proxy)
    • 可以理解明星和经纪人的关系,经纪人就是代理对象,明星就是目标对象
  • 织入(weaving)
    • 通过创建代理对象把切面应用到目标对象的过程

aop原理

文章中,笔者对sop的原理提出了自己的见解。我觉得有点意思,在这记录下来,完整版请看链接。 spring使用代理类伪装成目标类,当调用目标类方法时,会被代理类拦截到,代理类执行切面,再把调用目标类方法。 问题:怎么弄出来一个代理类? 方法一:和目标类实现相同的接口,即伪装成它的兄弟,这是Jdk动态代理 方法二:继承目标类,做它的儿子,这就是Cglib动态代理

配置示例

//描述切面类
@Aspect
@Configuration
public class TestAop {

    /*
     * 定义切入点,包括两部分,一个方法签名(返回值必须是void),另一个是切入点表达式
     */
    @Pointcut("execution(* com.test.service.CacheDemoService.find*(..))")
    public void excudeService(){
    
    }
	
    /**
     * 定义通知,需要指定切入点
     */
    @Around("excudeService()")
    public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint){
        System.err.println ("切面执行了。。。。");
        try {
            Thing thing = (Thing) thisJoinPoint.proceed ();
            thing.setName (thing.getName () + "=========");
            return thing;
        } catch (Throwable e) {
            e.printStackTrace ();
        }
        return null;
    }
    
    
    /*
     * 通过连接点切入
     * args:用于将参数值传入到通知方法中
     */
    @Before("execution(* findById*(..)) &&" + "args(id,..)")
    public void twiceAsOld1(Long id){
        System.err.println ("切面before执行了。。。。id==" + id);
    }
}
```

### 说下JoinPoint

任何通知方法可以将第一个参数定义为`org.aspectj.lang.JoinPoint`,JoinPoint接口提供了一系列有用的方法。

- getArgs():获取方法参数值
- getThis():获取代理对象
- getTarget():获取目标对象
- getSignature():获取目标方法的签名

![image-20210113151746445](https://gitee.com/ruihuaaa/online_storage/raw/master/img/20210113151753.png)