Spring之AOP基础知识

1.基本概念

切面(Aspect)带有advisor英文的都是切面:要增强的功能,都是切面,比如日志,事务,缓存等功能。

代理:内存中动态形成的对象

增强:具体的增强代码

切点: 连接点的集合

连接点:一个连接点对应一个被代理方法

2.切面Advisor的两个重要元素:切点pointcut和增强Advice
Pointcut来判断哪些类需要生成代理对象,进行增强。Adivce就是要增强的方法。
PonitCut中,通过ClassFilter拦截要代理的类,通过MethodMatcher拦截要增强的方法。
拦截方法是针对@Transactional等注解的方法。

3.Spring AOP的入口是AbstractAutoProxyCreator类的postProcessAfterInitialization方法,该类是个BeanPostProcessor类,在对象实例化完成后,有一个埋点,调用了这个方法,进行AOP,生成代理对象。

4.增强的注解总结 @Before @Around等。一个注解,会形成一个advisor切面类。@Aspect里写多个这种注解,就会生成多个advisor切面类。

6.MethodInvocation m=ExposeInvocationInterceptor.currentInvocation();
在增加方法里调用,可以获得当前参数?解决参数传递问题? 研究这个方法以及默认切面的生成。
AOP中三个工具类要知道:
ProxyFactory: 根据接口,接口类加载器等参数,获取到代理对象
AopUtils: 将当前代理对象放在了ThreadLocal中,如果使用了AOP,可以通过currentProxy方法获取当前的代理对象。
ExposeInvocationInterceptor:默认生成的拦截器链,排在拦截器的第一位。是将MethodInteceptor对象本身放在了ThreadLocal中,可以在当前线程中获得。

9.JDK动态代理是面向接口的,CGLIB是面像对象的。如果一个类没有接口,还用jdk动态代理,那spring会自动转成cglib。

11.ProxyFactory存放了切面等等元素,研究这个类,看是否能掌握AOP的实现原理。一个代理对象,对应着一个ProxyFactory和JdkDynamicAopproxy对象。而不是整个工程里只有一个ProxyFactory对象。

ProxyFactory里存着advisors切面类,targetSource被代理实例

12.代理对象在启动的过程就生成了。最终代理对象存储在一级缓存中

13.@Transactional注解的方法,代理原理研究。只要有@Transactional的方法,那么这个类就会生成代理类。而对于那些没有增强的方法,直接走反射调用,调用target对象的原生方法。对于需要加强的类,走advice增强代码。
如果同一个类里一个普通方法调用@Transactonal方法,直接调用,那么不会走代理的增强方法,而是走这个真实方法,这样就起不到增强的作用了。需要从applicationcontext.getBean中获取对象本身,这样拿到的是代理对象。然后用代理对象,调用@Transactional的方法,这样会走加强。
或者调用AopContext.currentProxy()获得当前对象的代理对象。

研究AopContext类的用法。

14.当用代理对象调用方法的时候,spring会遍历这个对象的所有切面,然后判断调用的方法是否是加强方法,如果是加强方法,则调用增强方法,如果不是,则调用原生方法。可见,spring也是通过循环遍历,来判断哪个方法是增强的,哪个方法是原生的。

16.自定义的@Around方法里,也要声明proceed()方法吗。否则链式调用会中断吗? @Around中的proceed方法和连接点的proceed方法不是一个类的方法。@Around中的proceed方法就是调用目标方法。而连接点的proceed方法是链式调用拦截器的方法

17@Autowired进来的对象,都是单例的,那么@Autowired多例对象,该如何呢?启动过程中,就已经定了@Autowired的对象,不管是单例还是多例,依赖注入时getBean就获到一个对象,所以,即使是多例,也是只拿到同一个对象。
如果想拿到不同的对象,应该怎么做呢,需要在scope注解中用proxyMode属性的TARGET_CLASS,将其变成代理对象。获取代理对象的时候,会多次调用getBean,多例就返回多个对象了。(想清楚其中原理)

疑问:被代理的对象,有@Component注解,spring容器中还会有这个类吗?被代理的对象,可以不用@Component修饰吗?
被代理的对象,即使没有@Component注解,也能纳入Spring容器。只不过这个对象不能通过@Autowired获得,只能通过ApplicationContext.getBean方法获得。

18.被代理对象类的注解,和方法上的注解,获取方式都发生了变化:
获取方法上的注解: Method method=AopUitls.getNostSpecificMethod(method,targetClass);
获取类上的注解:AnnotatedElementUtils.findMergedAnnotation(handler.getClass(),CIMHandler.class);
因为代理是面向接口的,所以直接拿是不行的,需要通过代理对象获取原生对象,再拿注解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的小小酥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值