一般手动启动spring容器和获取Bean实例我们会写如下代码:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("testBean.xml",getClass())); MyTestBean bean = (MyTestBean) bf.getBean("myTestBean");或者是
ApplicationContext beans=new ClassPathXmlApplicationContext("classpath:application-customTag.xml"); User user=(User)beans.getBean("testBean");第一行代码是启动spring容器;第二行代码是获取Bean实例;
那么这两行代码底层做了哪些事情呢,我们慢慢道来。
由图1可大致知道主要做了哪些事:
1.1 通过new ClassPathResource("testBean.xml",getClass())加载配置,返回Resource;
加载资源有多种方式,如:ClassPathResource、FileSystemResource、UrlResource等
1.2 通过new XmlBeanFactory(Resource resource)启动spring容器
一级主要代码:
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); public XmlBeanFactory(Resource resource) throws BeansException { this(resource, null); } public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); }
调用XmlBeanDefinitionReader的loadBeanDefinitions进行一级分析配置,其中XmlBeanDefinitionReader对资源的阅读器,spring源码中很多xxxReader的方法,通过该阅读器读取bean配置存放在BeanDefiniton中。
二级主要代码:
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); } public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isTraceEnabled()) { logger.trace("Loading XML bean definitions from " + encodedResource); } //通过属性来记录已经加载的资源 Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { //从encodedResource中获取已经封装 Resource对象并从中获取输入输入流 InputStream inputStream = encodedResource.getResource().getInputStream(); try { //InputSource并不是Spring中的类,它的全路径为org.xml.sax.InputSource //为XML实体的单个输入源,字节流 InputSource inputSource = new InputSource(inputStream);// if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } /** * the SAX InputSource to read from the resource descriptor for the XML file * 返回:the number of bean definitions found */ return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } }大致所做的事情是:
1.对传进来的Resource进行编码,类似加密
2.将编码后的Resource转化成字节输入流
3.通过InputSource inputSource = new InputSource(inputStream);生成一个InputSource,它的全路径为org.xml.sax.InputSource
用来对XML资源进行解析
4.调用int doLoadBeanDefinitions(inputSource, encodedResource.getResource())准备对配置进行解析
三级主要代码:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { Document doc = doLoadDocument(inputSource, resource); int count = registerBeanDefinitions(doc, resource); if (logger.isDebugEnabled()) { logger.debug("Loaded " + count + " bean definitions from " + resource); } return count; }该方法主要做三件事:
1.获取对XML文件的验证模式
2.加载XML文件,并得到对应的Document
3.根据Document注册Bean信息
其中Document doc = doLoadDocument(inputSource, resource);做前两件事情
代码为:
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception { return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware()); }其中getValidationModeForResource(resource)进行XML文件格式的验证;
EntityResolver的作用是项目本身就可以提供一个如何寻找DTD声明的方法,即由程序来实现寻找DTD声明的过程,比如我们将DTD文件放到项目中某处,在实现时直接将此文档读取并返回给SAX即可。这样就避免了通过网络来寻找相应的声明。
查找顺序:如果本地有,则不进行网络查找;本地没有,则进行网络查找,spring将DTD和XSD文件放在了项目中,防止网络查找时网络异常
int count = registerBeanDefinitions(doc, resource);做最后一件事情
代码为:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //使用DefaultBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //在实例化BeanDefinitionDocumentReader时候会将BeanDefinitionRegistry传入,默认使用继承自DefaultListableBeanFactory的子类 //记录统计前BeanDefinition的加载个数 int countBefore = getRegistry().getBeanDefinitionCount(); //加载及注册bean documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //返回记录本次加载的BeanDefinition个数 return getRegistry().getBeanDefinitionCount() - countBefore; }主要代码是int count = registerBeanDefinitions(doc, resource);注册BeanDefinitions,一个Bean内容存在一个BeanDefinition中,通过注册功能相当于将这些BeanDefinition存入内存中,以便用的时候获取。
后续主要代码:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //使用DefaultBeanDefinitionDocumentReader实例化BeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //在实例化BeanDefinitionDocumentReader时候会将BeanDefinitionRegistry传入,默认使用继承自DefaultListableBeanFactory的子类 //记录统计前BeanDefinition的加载个数 int countBefore = getRegistry().getBeanDefinitionCount(); //加载及注册bean documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //返回记录本次加载的BeanDefinition个数 return getRegistry().getBeanDefinitionCount() - countBefore; } public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; doRegisterBeanDefinitions(doc.getDocumentElement()); } protected void doRegisterBeanDefinitions(Element root) { //BeanDefinitionParserDelegate为BeanDefinition分析器委派类 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { //获取profile属性,profile是<beans>的属性,可以与web.xml配合使用部署两套配置来适用于测试环境和生产环境 //这样可以方便的进行切换不同环境,最常用的是更换不同的数据库 String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); //如果 定义了profile属性 if (StringUtils.hasText(profileSpec)) { /** * profile属性值可能是多个,如:profile="dev,prod",tokenizeToStringArray是将profile字符串转换 * 成字符数组 */ String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); // We cannot use Profiles.of(...) since profile expressions are not supported // in XML config. See SPR-12458 for details. if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isDebugEnabled()) { logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } /** * 解析前处理(空函数),运用了设计模式中的模板模式,如果继承自DefaultBeanDefinitionDocumentReader * 的子类需要在Bean解析前后做一些处理的话,那么只需要重写这个方法就可以了(postProcessXml也是一样的) */ preProcessXml(root); //解析 parseBeanDefinitions(root, this.delegate); //解析后处理(空函数) postProcessXml(root); this.delegate = parent; } protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { //对Beans的处理 if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //默认命令空间,对bean处理,如<bean id="id1" class="test.id"> //BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans"; parseDefaultElement(ele, delegate); } else { //自定义命令空间,对bean处理,如:<tx:annotation-driver/> delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //解析import标签 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); }//解析alias标签 /** * <alias name="dataSource" alias="dataa"/> * <alias name="dataSource" alias="datab"/> *<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > *在对bean进行定义时,除了使用id属性来指定名称之外,为了提供多个名称,可以使用alias标签来指定。而所有的这些名称都 *指向同一个bean */ else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); }//解析bean标签 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); }//解析beans标签 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // 循环递归解析 doRegisterBeanDefinitions(ele); } } @Nullable public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { //获取对应的命名空间如:http://www.cb.com/schema/user String namespaceUri = getNamespaceURI(ele); if (namespaceUri == null) { return null; } //根据命名空间找到对应的NamespaceHandler,如: NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } //此时的handler已经被实例化为自定义的Handler实例 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }注:在解析配置文件前后定义好空模板,由子类去实现相关逻辑,运用了设计模式中的模板模式
一级代码:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //提取对应的beanName /** * 要什么需要这一步,因为传入的参数name可能是别名也可能是FactoryBean,需要分情况做如下处理 * 1.如果是FactoryBean,则去除FactoryBean的修饰符,也就是如果name="&aa",那么会首先去除&而使用name="aa" * 2.取指定alias所表示的最终的beanName,例如别名A指向名称为B的bean则返回B,若别名A指向别名B,别名B又指向别名 * 为C的bean,则最终返回C名称 */ final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. /** * 检查缓存中或者实例工厂中是否有对应的实例 * 为什么首先会使用这段代码呢,因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候 * 为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光 * 也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用beanFactory */ //直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) {//从缓存或者ObjectFactory中获取到了实例 if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } //返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例 //bean的实例化 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else {从缓存或者ObjectFactory中没有获取到了实例 // Fail if we're already creating this bean instance: //如果我们已经创建了这个Bea实例则会失败: // We're assumably within a circular reference. /** * 只有在单例情况才会尝试解决循环依赖,原型模式情况下如果存在A中有B的属性,B中有A的属性,那么当依赖注入 * 的时候,就会产生当A还未创建完的时候因为对应B的创建再次返回创建A,造成循环依赖,就是下面的情况 */ //原型模式的依赖检查 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. //检查该bean定义是否存在ParentBeanFactory中 BeanFactory parentBeanFactory = getParentBeanFactory(); //如果当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试 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 if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } //如果不是类型检查则是创建bean,这里要记录 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName //是子Bean的话同时会合并父类的相关属性 /** * 因为从XML配置文件中读取到的Bean信息是存储在GernericBeanDefinition中的,但是所有Bean后续处理 * 都是针对于RootBeanDefinition的,所以这里转换一下 */ final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //保证当前bean依赖的bean的初始化 /** * bean的初始化过程中有可能用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么 * 这个时候就有必要加载依赖的bean,所以,在spring的加载顺序中,在初始化某一个Bean的时候首先会初始化这个bean * 所对应的依赖 */ String[] dependsOn = mbd.getDependsOn(); //如果存在依赖则需要递归实例化依赖的Bean 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); } } } /** * 以下操作是针对不同的scope进行不同的初始化策略,对bean进行创建 */ // 单例模式创建Bean实例. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //原型模式创建Bean 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 {//指定Scope实例化Bean 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. //检查所需类型是否与实际bean实例的类型是否匹配,不匹配做相应的转换 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.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }以单例模式新创建Bean实例继续跟踪底层源码:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. //锁定class,根据设置的class属性或者根据className来解析Class Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 验证及准备覆盖的方法 /** * 其实是处理lookup-method和replace-method的。 * 在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置 * 统一存放在BeanDefinition中的methodOverrides属性里,这两个功能实现原理其实是在bean实例化的时候 * 如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理 */ try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //创建实例前做了一些处理 //应用初始化前的后处理,解析指定bean是否存在初始化前的短路操作 /** * 实例化bean之前就为bean初始化定义一些后处理事项,有两个方法: * postProcessBeforInitializationBean:初始化之前被回调 * postProcessAfterInitialization:Bean初始化之后被回调 */ Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean;//直接返回 } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //实际创建Bean的操作 //常规Bean的创建 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }这里重点提下:Spring提供了一中叫做BeanFactoryPostProcessor的容器扩展机制。该机制允许我们在容器s实例化相应对象之前,对注册在容器中的BeanDefinition所保存的信息做相应的修改,让我们对最终的BeanDefinition做一些额外的操作,比如修改其中Bean定义的某些属性,为bean定义增加其他信息等。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);就是实现了这个扩展机制。
该方法的代码是:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //实例化前的后处理器应用 /** * bean的实例化前调用,也就是将AbstarctBeanDefinition转换为BeanWapper前的处理 * 给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们 * 认为的bean,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过 * 其他技术生成的 */ //在目标Bean初始化之前被回调。 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { //实例化后的后处理器应用 //在目标Bean初始化之后被回调。 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }通过Object beanInstance = doCreateBean(beanName, mbdToUse, args)对常规Bean进行创建。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 实例化Bean BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化 instanceWrapper = createBeanInstance(beanName, mbd, args); } //org.springframework.beans.factory.support.LookupMethodTests$AbstractBean$$EnhancerBySpringCGLIB$$9976ee6a@2bb3058 final Object bean = instanceWrapper.getWrappedInstance(); //class org.springframework.beans.factory.support.LookupMethodTests$AbstractBean$$EnhancerBySpringCGLIB$$9976ee6a Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. //允许后处理器修改合并的bean定义 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references //急切地缓存单例以便能够解析循环引用 // even when triggered by lifecycle interfaces like BeanFactoryAware. //即使由BeanFactoryAware等生命周期接口触发 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂 //对bean再一次依赖引用,主要应用SmrtInstantitationAware BeanPostProcessor,其中 //我们熟知的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. //初始化bean实例 Object exposedObject = bean; try { //对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean //填充bean populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 将bean注册为一次性(用完就销毁) try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. //没有可填充的属性 return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. //给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean //如:可以用来支持属性注入的类型 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //返回值为是否继续填充bean if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } //如果后处理器发出停止填充命名则终止后续的执行 if (!continueWithPropertyPopulation) { return; } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. //根据名称自动注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. //根据类型自动注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //后处理器已经初始化 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); //需要依赖检查 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //对所有需要依赖检查的属性进行后处理 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } //依赖检查,对应depend-on属性,3.0已经弃用此属性 checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { //将属性应用到bean中 applyPropertyValues(beanName, mbd, bw, pvs); } } 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 { //对特殊的bean处理 :Aware、BeanClassLoaderAware、BeanFactoryAware invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //应用之前定义的初始化前回调的后处理器 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //激活用户自定义的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()) { //应用之前定义的出生后回调的后处理器 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } //返回初始化后的bean return wrappedBean; }该方法主要做的事情有:
1.根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
2.装配Bean依赖(对Bean进行相关属性填充)
3.Bean初始化前定义一些后处理事项,有初始化前回调方法,初始化后回调方法
4.Bean初始化
5.对象其他处理
6.注册回调接口(如:销毁Bean)