源码入口# 上篇博文中我们看到了将Spring环境中的 BeanPostProcessor找出来,添加到BeanFactory中的beanPostProcessors中,统一维护,本片博文继续往下拓展,看下Spring如何实例化bean,以及如何实现在bean的实例化通过各种各样的后置处理器完成bean的增强 所以本次的程序入口是AbstractApplicationContext中的finishBeanFactoryInitialization(beanFactory);,源码如下,主要做了如下几件事 Copy protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. // 为上下文初始化类型转换器 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // 检查上下文中是否存在类型转换器 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。 // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. // 禁止使用临时类加载器进行类型匹配 beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes // 允许缓存所有的bean的定义数据 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 准备实例化bean beanFactory.preInstantiateSingletons(); } 我们着重看他是如何创建实例化bean的,跟进beanFactory.preInstantiateSingletons();,调用beanFactory的方法准备实例化bean, 这个beanFactory就是Spring默认是bean工厂, DefaultListableBeanFactory, 源码如下:方法不算很长,逻辑也很清楚, 一开始Spring取出当前上下文中所有的BeanName列表,因为在执行到这里之前,已经完成包扫描了所以说这个盛放beanName的list里面存放的就是所有的需要实例化的对象的全集,包含Spring自己的,和程序员自己添加的还包含Aspectj的 所以说,当前方法的目标很明了,就是遍历这个list中的每一个beanName,然后实例化当前beanName相应的bean 当然,如果想实例化,前提是不能是抽象类,不能是接口,非懒加载, 而且针对FactoryBean还有不同的处理模式 Copy public void preInstantiateSingletons() throws BeansException { if (logger.isDebugEnabled()) { logger.debug("Pre-instantiating singletons in " + this); } //所有bean的名字 // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. //todo 遍历一个副本以允许init方法,而init方法反过来注册新的bean定义。 // todo 盛放所有的beanName,所有的需要实例化的beanName都在这里,包括Spring断断续续添加的, Aspectj的, 程序员通过注解标识的 List beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // todo 触发所有非延迟加载单例beans的初始化,主要步骤为调用getBean for (String beanName : beanNames) { // todo 合并父类BeanDefinition,可以进入查看 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //todo 三个条件,抽象,单例,非懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); // todo 如果是FactoryBean则加上& // todo 检验是否是 FactoryBean 类型的对象 if (bean instanceof FactoryBean) { final FactoryBean factory = (FactoryBean) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { // todo 因为我们没有添加FactoryBean类型的对象, 一般都会进入这个getBean getBean(beanName); } } } 下面接着跟进getBean(beanName);方法,顾名思义获取Bean,再往下跟下去,就算是本文的正文开始部分了,但是我想在这里级具体一下,一个比较有分量的剧透吧,当前的getBean(beanName)它是有返回值的,一会当我们往下跟进的是时候会发现会存在递归的现象,这一点巧妙的实现了@Autowired处理setter方式实现循环引用 ok,现在继续看代码,经过了几个空方法的传递,我们来到下面的代码中,它主要做了如下几件事 首先将传递进来的name转换成了beanName 原因1: FactoryBean的实现类的存储方式和其他的类完全相同,添加上&是获取不到的, 因此我们将&去掉 原因2: 解决别名的问题 为什么在创建bean之前先调用getSingleton()? 回想一下,现在是Spring启动的过程中,是在准备实例化bean,为什么一开始就来getSingleton(),跟进源码查看这个方法,它最终实现中有一行代码是这样的Object singletonObject = this.singletonObjects.get(beanName);而这个singletonObjects就是微观层面的IOC容器,循环创建刚开始时,IOC确实是空的,但是我前面存在剧透,一开始的getBean()方法是存在递归调用现象的,直接举2个例子: 第一:假如现在在实例化A,结果有发现需要给A注入B, 那Spring是不是得获得B,怎么获得呢? 递归使用getBean(BName)完成, 第二个例子: A被添加上了@Lazy注解,是懒加载的,但是终究有一个会通过getBean(AName)获取A,这是发现A是实例化需要B,B肯定已经实例化完事了,同样是通过递归getBean(BName)实现注入, 在这两个过程中就是getSingleton()保证不会重复创建已经存在的实例 我们关注的重点其实是第二个getSingleton(beanName()->{xxx}) 在第二个getSingleton()方法中才是真正的去实例化bean的方法 最后,在当前的方法最后将bean返回了 前面我就是说过了,getBean(beanName)存在递归调用的情况,为什么我会一直说这个事呢,因为如果不知道这个事的话,这些代码看起来是没有头绪的,但是明白这个事,看代码就变得很有逻辑,我在简单总结一下怎个玩这个递归呢? 假设现在通过getBean(AName)来注入A对象,但是呢发现了A依赖B对象,于是在getBean(AName)里面调用getBean(BName),通过这个方法返回出B对象完成A的注入 Copy protected T doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 将传递进来的name final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 及早的检查一下有没有已经注册了的单例对象 Object sharedInstance = getSingleton(beanName);// todo ::: name=myService时,这次来调用的就是 DefaultSingletonBeanRegistry中的 getSingleton() , 不同之处是多传递了一个true if (sharedInstance != null && args == null) { // 如果存在的话,将其取出赋值给bean,后续直接返回这个bean bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // 来到这里就说明要获取的bean还没有实例化过 // 于是检验一下,如果是原形,直接抛异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 检查是否存在默认的父工厂 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { // 将当前的beanName存放到AlreadeyCreated这个set集中,标识这个bean被创建了 markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 确保当前bean所依赖的bean都已经初始化好了 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. if (mbd.isSingleton()) { // 实例化bean sharedInstance = getSingleton(beanName, () -> { // 真正的完成bean的创建 return createBean(beanName, mbd, args); }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 下面是进行其他的检查工作,这里不再深究了 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } 经过了上面一顿扯,然后我们继续往下跟,看看createBean(beanName, mbd, args)方法中是如何实例化我们的Bean的, 上面的方法是在AbstractBeanFactory中,createBean(beanName, mbd, args)是它的抽象方法, 那实现类是哪个呢? AbstractAutowireCapableBeanFactory,隆重的夸一下这个类,Spring都称赞这个类是有有才华的 todo 总结这个类 在这个方法中,主要做了两件事:两件大事!!! 第一件大事: 在实例化Bean前,第一次调用后置处理器, 这件大事绝对是有历史意义的!!!为啥呢?大家想想,bean还没有创建呢!就已经可以插手bean的创建过程了,不是很刺激吗?接着看回调了什么后置处理器呢? Spring会循环所有的处理器检查当前被遍历的处理器是否是InstantiationAwareBeanPostProcessor类型的,如果是的话呢,就执行这个后置处理器的postProcessBeforeInstantiation(beanClass, beanName);方法 这个postProcessBeforeInstantiation()是允许有返回值的,大家可以想想,这一点是不是有点可怕? 事实也是这样,后置处理器的目的是为了增强对象,而我们却可以在这里返回一个任何东西,狸猫换台子替换掉原始的,还没有被创建的对象,还有一点,就是一旦我们在这里真的是没有返回null,那后续Spring就没有义务在去为我们创建本来应该创建的对象了,代码通过if-else的选择分支会使得当前的对象不再经历其他后置处理器的增强,最终执行它父类的postProcessorAfterInitialization() 补充一点,我们通过@EnableAspectjAutoProxy添加到Spring上下文中的AnnotationAwareAspectjAutoProxyCreator对象其实就是这个类型InstantiationAwareBeanPostProcessor,也就是说在这里这个接口的相关方法会被回调,下面看看他的实现类AbstractAutoProxyCreator对这个before()方法的重写实现,源码如下: 主要逻辑就是找出需要产生代理增强的bean(切面类),和普通的bean, 需要增强的bean放在advisedBeans里面,因为需要增强的bean是需要动态植入其他逻辑的,所以不放在一起 判断当前bean是否是基础类型的,比如: Advice PointCut Advisor AopInfrastructureBean 或者是 切面Aspectj 都算是基础类型,标注这些信息的类,是不会被增强的,标记false 主意啊,上面说的都是作用都是进行了一下标记 Copy //todo 跟进来 @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } // todo 亮点就是在这里, 如果是我们切面类来到这里,条件是满足的 // todo advicedBeans 见名知意: 通知beans // todo Spring用它标识, 被放在这个方法中的类,全部都不会被增强 // todo 满足什么条件时,通过检查呢? 就是检查是否标记有 @Aspectj @Before ... 等注解 // todo 说的再直接一点, 就是返回了null, 表示当前的切面仍然需要按照正常的流程创建出来,但是这里进行标记了 if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // Create proxy here if we have a custom TargetSource. todo 如果我们有一个自定义的TargetSource,在这里创建代理 // Suppresses unnecessary default instantiation of the target bean: // todo 抑制不必要的目标bean的默认实例化: // The TargetSource will handle target instances in a custom fashion. todo TargetSource将以自定义方式处理目标实例。 TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (Stri