20200208_Spring AOP源码脉络分析

Spring AOP源码脉络分析

客户端通过getBean获取bean,实际是调用了

   AbstractApplicationContext.getBean(String name)
   AbstractApplicationContextImpl.getBeanFactory().getBean(name)
   AbstractBeanFactory.doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
   AbstractBeanFactory.getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd)
   FactoryBeanRegistrySupport.getCachedObjectForFactoryBean(String beanName)

最终是从一个factoryBeanObjectCacheConcurrentHashMap获取Bean。从这点上,必定会有一个地方将创建的bean通过Map.putfactoryBeanObjectCache

通过AbstractBeanFactory.getObjectForBeanInstance方法可知:

if (mbd == null) {
   object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
   // Return bean instance from factory.
   FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
   // Caches object obtained from FactoryBean if it is a singleton.
   if (mbd == null && containsBeanDefinition(beanName)) {
      mbd = getMergedLocalBeanDefinition(beanName);
   }
   boolean synthetic = (mbd != null && mbd.isSynthetic());
   object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;

首次加载的时候,会调用AbstractBeanFactory.getObjectFromFactoryBean(factory, beanName, !synthetic)

这里的重点逻辑:

try {
	object = postProcessObjectFromFactoryBean(object, beanName);
}

postProcessObjectFromFactoryBean实际调用了AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(object, beanName)

for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
   result = beanProcessor.postProcessAfterInitialization(result, beanName);
   if (result == null) {
      return result;
   }
}

这段代码拿到AbstractAdvisingBeanPostProcessor并调用postProcessAfterInitialization,在postProcessAfterInitialization中调用了ProxyFactory.getProxy(ClassLoader classLoader)

return proxyFactory.getProxy(getProxyClassLoader());

proxyFactory.createAopProxy方法中获取DefaultAopProxyFactory并调用createAopProxy

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException();
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

其中:

  • config.isOptimize():是否对生产代理策略使用优化

    • true:进行优化,如果有接口就代理接口(使用JDK动态代理),没有接口代理类(CGLIB代理);
    • false:不进行优化(默认值是false)
  • config.isProxyTargetClass():是否强制使用CGLIB来实现代理

    • true : 强制使用CGLIB来实现代理

    • false:不强制使用CGLIB来实现代理,首选JDK来实现代理(默认值也是false

  • hasNoUserSuppliedProxyInterfaces(config):判断代理对象是否有实现接口

以上方法就是判断用哪种方式创建代理对象,

ObjenesisCglibAopProxy(继承CglibAopProxy)
JdkDynamicAopProxy

返回的AopProxy再调用getProxy,最终调用的是Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

Proxy底层是通过反编译代理类的产生字节码进行增强处理的

byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);

由于jdk的动态代理生成的新的类是默认继承自Proxy的,且JAVA不支持多继承,所谓为了能够生成代理类,只能通过实现被代理类的接口的方式来达到目的,这也是为什么JDK动态代理要求代理对象是基于接口的原因.

附:

  • 简化了的时序图
    在这里插入图片描述
  • 阅读源码的几个技巧
  1. 条件断点:通过对断点设置条件(一般的IDE都支持)来精准拦截预设值
  2. 聚焦主题:只关注我们关心的源码,对其他不影响的方法不去关注,但要知道方法的作用
  3. 对于关注的对象的运行结果,明确结果是否存在后,放过对于相反(即不存在情况下)的代码逻辑的阅读与分析
  4. 对于不知道后续的运行结果如何,避免重新跑一遍程序,可通过IDE提供的evaluate expresssion来即时计算表达式的值

一句话总结AOP原理: 通过反编译被代理对象产生的字节码,结合JVM指令生成新的代理对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值