Spring AOP

本文详细解析了Spring框架中ProxyFactoryBean的工作原理,包括初始化Advisor链、生成代理类以及调用时的拦截过程。介绍了如何通过配置interceptorNames生成Advisor链,以及在singleton和prototype模式下代理对象的创建机制。
摘要由CSDN通过智能技术生成

ProxyFacotryBean是FacotryBean的一种实现,FacotryBean要产生bean都要重写getObject方法,而ProxyFacotryBean这里的这个getObject正是为代理做了准备并返回代理对象。首先用initializeAdvisorChain(第一次去取代理对象时初始化一遍)初始化Advisor链后对于singleton和prototype进行区分生成对应的proxy。

1、初始化Advisor链

      initializeAdvisorChain初始化Advisor链是遍历ProxyFacotryBean中配置的interceptorNames,如果结尾有通配符只能是ListableBeanFacotory来加载否则报错,去掉结尾通配符*后调用addGlobalAdvosor(这个是获取ListableBeanFacotory的所有globalAdvisorNames和globalInterceptorNames,分别遍历用getBean(beanName)获取advice,把其中符合通配符格式的advice调用addAdvisorOnChainCreation封装成advicsor后添加到Advisor链,如果结尾没有通配符的情况下无论是singleton还是prototype在获得advice后都要用addAdvisorOnChainCreation方法注册到advisor链上。

    addAdvisorOnChainCreation用namedBeanToAdvisor方法把advice包装成advisor,判断如果advice是单例singleton的话是用AdvisorAdapterRegistry(默认DefaultAdvisorAdapterRegistry单例)wrap方法判断如果这个advice是MethodInterceptor或者AdvisorAdapterRegistry三种固定的adapter(before,afterreturning,throws)如果任一adapter支持的话(支持不支持就是在具体的adapter中判断advice是不是这个adapter对应具体的advice类的子类)就封装成DefaultPointcutAdvisor返回。如果是prototype的话不获取getBean,而是直接用name包装成PrototypePlaceholderAdvisor。

2、生成代理类

      以singleton为例,singleton代理的生成getSingletonInstance方法。是用AopProxyFactory(在构造器中设定了默认的DefaultAopProxyFactory)的createAopProxy方法根据ProxyFacotryBean中配置的target判断是否是个接口(实际上不是这么简单的区分,具体看源码了解)来创建不同AopProxy的子类(JdkDynamicAopProxy或者ObjenesisCglibAopProxy(CglibAopProxy的子类,增加了ObjenesisStd))调用他们各自的getProxy方法以不同的方式创建代理对象返回。

      JdkDynamicAopProxy就是以动态代理的方式构建代理对象返回(具体动态代理原理自行了解哦)。

      CglibAopProxy就是以Cglib的方式进行代理,Cglib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。具体细节超出这文章的范围拉。

      prototype代理的方式大致相同有些许的差别也不做介绍,可以参考源码。

3、调用时拦截

      在调用目标类的方法时因为代理调用的是invoke(jdk动态代理)或者intercept(cglib)。在invoke(jdk动态代理)或者intercept(cglib)中根据目标类被调用方法分别处理。

      如果是hashCode和equals方法直接调用代理类中重写了的hashCode和equals方法(具体参考源码)。
      如果是Adviced接口中定义的方法(ProxyFactoryBean就是Adviced接口实现类)直接以反射的方式拿到method调用方法(AopUtils的invokeJoinpointUsingReflection方法)。
      其他情况就是拿到拦截器链(只初始化一次,每次调用时有个currentInterceptorIndex记录处理到第几个拦截器)调用拦截器的proceed方法前进调用。

      proceed前进调用不是递归,其中用matcher进行匹配,如果匹配上调用拦截器的invoke方法,匹配不上就直接继续前进调用,拦截器interceptor的invoke方法就是通知方法(自己实现的如afterReturning等)对目标方法(实际是拦截器链的proceed前进调用)的具体加强,就是顺序问题等等。

      直到拦截器链前进到底调用target目标类的对应方法(jdk反射获取method调用)。

      初始化拦截器链是通过遍历之前IOC容器getBean获取到advisor链中的Advisor,通过AdvisorAdapterRegistry当中设置的3种adapter(before,afterreturning,throws)的supportsAdvice判断是否支持该advisor,如果支持就将advisor中的advice注册成不同的AdviceInterceptor列表(一个advisor可以被多个adapter支持,因为只要自己写的通知类实现多种advice接口即可)都加入到拦截器链。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT学习道场

为你的进步加点油!

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

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

打赏作者

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

抵扣说明:

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

余额充值