参考资料: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)