Spring 源码阅读之 深入理解 finishBeanFactoryInitialization (8)

我们一路往下跟进resolveDependency()我们关注这个方法如下代码:

if (instanceCandidate instanceof Class) {// todo !!!!!当运行到这行代码时, myService还没有被实例化(singletonObjects中没有) 执行完这一个行代码之后, IndexDao1完成了对myService的装配 instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); }

跟进这个resolveCandidate()源码如下:

很直接发现,出现的递归的现象,这其实解析清楚了Spring是如何完成属性注入的,就是只不过前前后后很多接口很多类,会扰乱这个阅读的过程

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException { // todo 从bean工厂的获取, beanName = myService requiredType = com.changwu...OrderService2 , 跟进去这个方法, 他调用了AbstractBeanFactory中的getBean(){ doGetBean();} return beanFactory.getBean(beanName); }

完成装配后,其实现在的对象依然是原生的java对象 回到AbstractAutowireCapableBeanFactory中的initializeBean()方法,源码如下, 看了下面的代码就是知道了为什么applyBeanPostProcessorsBeforeInitialization和init()和applyBeanPostProcessorsAfterInitialization()之间的调用顺序了

还有最后一个秘密需要揭开: Spring的AOP不是产生了代理对象? 那什么时候完成的代理呢?毕竟从我开始写这篇文章到最后都没有看到,其实AOP的实现就在下面的代码中

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //todo 执行全部的后置处理器的 Before方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // todo 执行所有的init方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // todo 执行所有的后置处理器的 after方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

我们在前面知道当遇到这个AbstractAutoProxyCreator时,回调它的before()方法时,仅仅是标记哪些对象需要进行增强哪些对象不需增强,而没有立即生成代理对象

现在我们关注这行代码wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); ,生成代理对象的逻辑就在这里面

@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // todo 进入 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }

看这个方法wrapIfNecessary(bean, beanName, cacheKey);最终会进入这个实现中

大家可以看到Spring为bean生成了代理对象,默认会先检查被代理的对象有没有实现接口,如果实现了接口,就是用jdk动态代理,否则就看看有没有cglib的相关依赖,如果存在的相关依赖而没有实现接口,就会使用cglib的代理模式

另外,补充通过编码的方式控制 下面的if条件

config.isOptimize() -> 可以通过XMl配置, 默认false

config.isProxyTargetClass() -> @EnableAspectjAutoPeoxy(true) 默认也是false

@SuppressWarnings("serial") public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @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("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { //todo 目标对象是一个接口, 同样是使用jdk的动态代理 return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { // todo 所以默认使用的是 jdk的动态代理 return new JdkDynamicAopProxy(config); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxjdw.html