4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
彻底弄懂Spring中Bean的解析、创建和使用 - 云+社区 - 腾讯云
来自 : 腾讯云计算 发布时间:2021-03-25
彻底弄懂Spring中Bean的解析、创建和使用 - 云+社区 - 腾讯云菜单腾讯云备案控制台云+社区专栏视频精选问答沙龙团队主页开发者手册智能钛AI腾讯云大学TVP 搜索搜索关闭创作写文章发视频提问登录注册展开腾讯云·社区登录云+社区首页专栏视频精选问答沙龙团队主页开发者手册智能钛AI腾讯云大学TVP返回腾讯云官网石奈子26 篇文章彻底弄懂Spring中Bean的解析、创建和使用 转到我的清单专栏首页石奈子的Java之路彻底弄懂Spring中Bean的解析、创建和使用 10分享

分享文章到朋友圈

分享文章到 QQ分享文章到微博复制文章链接到剪贴板海报分享

海报分享

彻底弄懂Spring中Bean的解析、创建和使用 2020-06-282020-06-28 11:09:35阅读 2250Spring加载Bean、实例化Bean、获取Bean流程

本文旨在通过分析源码的方式,来剖析Spring加载Bean、实例化Bean、获取Bean的流程,部分核心内容会在源码中说明。内容比较枯燥,慎入!

第一步,启动一个Spring项目Spring启动入口

从官方文档中我们可以获取到下面这种Spring的启动方式。

我们传入一个test.xml文件

ApplicationContext context = new ClassPathXmlApplicationContext( classpath:/spring/test.xml 
xml文件内容
 ?xml version= 1.0 encoding= UTF-8 ?  beans xmlns= http://www.springframework.org/schema/beans  xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance  xsi:schemaLocation= http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd bean id= stringutil >bean对象(StringUtils)
public class StringUtils{// some code}
源码分析之Bean解析

从源码层面分析Bean解析过程、实例化过程、

入口 ClassPathXmlApplicationContext

先看下类图,后续源码中会反复用到不同层级中的代码。

ClassPathXmlApplicationContext实例化
 public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); // 省略some code  public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); //当前ClassPathXmlApplicationContext也是resource的子类 setConfigLocations(configLocations); //前边传入的refresh为true,执行 refresh方法 if (refresh) { refresh();}
AbstractApplicationContext#refresh

org.springframework.context.support.AbstractApplicationContext#refresh,AbstractApplicationContext是ClassPathXmlApplicationContext的父类。而这里的refresh则是覆写了ConfigurableApplicationContext的refresh方法

 public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // refresh的前置准备,比如设置startTime,开启激活状态、关闭close状态等等等 prepareRefresh(); //告诉子类去刷新内容Bean工厂(从类图中可以明显看出来入口类实例也是个bean工厂) // 观察和刷新BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //提前设置一些在该context中使用的属性,比如Classloader、Callback、environment等 prepareBeanFactory(beanFactory); try { // 通知context子类,后置处理beanFactory。比如用一系列的Webcontext子类 postProcessBeanFactory(beanFactory); // 将BeanFactoryPostProcessor在当前Context中注册为Bean invokeBeanFactoryPostProcessors(beanFactory); // 注册BeanPostProcessor来拦截Bean创建的后置处理。 registerBeanPostProcessors(beanFactory); // 为当前Context初始化MessageSource initMessageSource(); // 为当前context初始化应用事件广播 initApplicationEventMulticaster(); // 初始化其他特殊的bean对象 比如webcontext onRefresh(); // 检查监听Bean 并发布他们(ApplicationListener) registerListeners(); // 实例化BeanFactory中所有的其他的单例对象集合(非延迟的) finishBeanFactoryInitialization(beanFactory); // 最后发布LifecycleProcessor和ContextRefreshedEvent事件 finishRefresh(); catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn( Exception encountered during context initialization - + cancelling refresh attempt: + ex); // 失败销毁bean destroyBeans(); // Reset active flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; finally { // Reset common introspection caches in Spring s core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); }
BeanFactory创建

如果你了解BeanFactory,会知道此类是Spring重要的基础对象.

扩展BeanFactory讲解 是访问Spring Bean容器的根接口。是一个基础的client,功能更多的有比如ListableBeanFactory、ConfigurableBeanFactory。 这个接口的实现类,一般都会持有多个BeanDefinition对象信息,比如数量,Scope、实例、名称等。(可对比ListableBeanFactory) BeanFactory是Application组件的一个中央注册处(登记) 通常来说,BeanFactory会加载来自比如Xml的配置源中的Bean数据,并存储在工厂中。 如果是HierarchicalBeanFactory的话,ListableBeanFactory中的几乎所有方法都会检查是否是父工厂。 beanFactory应该支持以下的标准生命周期
 li BeanNameAware s {@code setBeanName} * li BeanClassLoaderAware s {@code setBeanClassLoader} * li BeanFactoryAware s {@code setBeanFactory} * li EnvironmentAware s {@code setEnvironment} * li EmbeddedValueResolverAware s {@code setEmbeddedValueResolver} * li ResourceLoaderAware s {@code setResourceLoader} * (only applicable when running in an application context) * li ApplicationEventPublisherAware s {@code setApplicationEventPublisher} * (only applicable when running in an application context) * li MessageSourceAware s {@code setMessageSource} * (only applicable when running in an application context) * li ApplicationContextAware s {@code setApplicationContext} * (only applicable when running in an application context) * li ServletContextAware s {@code setServletContext} * (only applicable when running in a web application context) * li {@code postProcessBeforeInitialization} methods of BeanPostProcessors * li InitializingBean s {@code afterPropertiesSet} * li a custom init-method definition * li {@code postProcessAfterInitialization} methods of BeanPostProcessors * /ol  * p On shutdown of a bean factory, the following lifecycle methods apply: * ol  * li {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors * li DisposableBean s {@code destroy} * li a custom destroy-method definition
AbstractApplicationContext#obtainFreshBeanFactory继续BeanFactory创建过程分析
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 如果已经有了工厂直接销毁,然后再建工厂 refreshBeanFactory(); //基本是从上边创建的beanFactory拿的 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug( Bean factory for + getDisplayName() + : + beanFactory); return beanFactory; }
AbstractRefreshableApplicationContext#refreshBeanFactory

org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory。如果已经有了工厂直接销毁,然后再建工厂。新建工厂会loadBeanDefinitions.

扩展BeanDefinition术语

BeanDefinition描述一个Bean实例具有的属性,比如Scope(单例还是Prototype),beanClassName、是否延迟加载,依赖等等等(还有些其他的属性)。当然这个是最小的BeanDefiniton接口,比较常用的子类实现有RootBeanDefinition,功能更为强大。

回到BeanFactory创建。
 protected final void refreshBeanFactory() throws BeansException { //如果有bean工厂销毁bean,关闭bean工厂 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); try { //创建 DefaultListableBeanFactory 而此工厂是BeanDefinitionRegistry的一个子类 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); //加载BeanDefinition(该例中是解析Xml中的Bean标签,并装载到BeanDefinition中) loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { //赋值给Context中的beanFactory this.beanFactory = beanFactory; catch (IOException ex) { }
AbstractXmlApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory)

org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)。 我们这里只是当前Xml方式的示例会进入此处。

 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 使用给定的beanFactory(BeanDefinitionRegistry) 来创建XmlBeanDefinitionReader实例 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context s // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); // ClassPathXmlApplicationContext也是一个ResouceLoader beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. initBeanDefinitionReader(beanDefinitionReader); // 通过XmlBeanDefinitionReader解析生成BeanDefinition loadBeanDefinitions(beanDefinitionReader); //接上 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); // 入口中传入的test.xml被存放在this.configLocations上,这里可以拿到。 String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); }
AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)

org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)。根据传入路径读取。

 public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException { Assert.notNull(locations, Location array must not be null  int counter = 0; for (String location : locations) { counter += loadBeanDefinitions(location); return counter; //接上 public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return loadBeanDefinitions(location, null); // 接上  // 从类图中可知 this对象(ClassPathXmlApplicationContext) 也是DefaultResourceLoader实例,已经被set进reader中,所以走else逻辑 public int loadBeanDefinitions(String location, Set Resource actualResources) throws BeanDefinitionStoreException { ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException( Cannot import bean definitions from location [ + location + ]: no ResourceLoader available  if (resourceLoader instanceof ResourcePatternResolver) { // Resource pattern matching available. try { Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); int loadCount = loadBeanDefinitions(resources); if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); if (logger.isDebugEnabled()) { logger.debug( Loaded + loadCount + bean definitions from location pattern [ + location + ]  return loadCount; catch (IOException ex) { throw new BeanDefinitionStoreException( Could not resolve bean definition resource pattern [ + location + ] , ex); else { // 只能加载从绝对路径加载单resouce location为我们传入的test.xml 路径 Resource resource = resourceLoader.getResource(location); //我们再继续跟进!!! int loadCount = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); if (logger.isDebugEnabled()) { logger.debug( Loaded + loadCount + bean definitions from location [ + location + ]  return loadCount; }
XmlBeanDefinitionReader#loadBeanDefinitions(Resource)

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource) 。从xml中加载Bean

 public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { //... 省略代码 try { // 前边我们传入的test.xml的输入流 InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); //真正的从xml中load bean definition return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); finally { inputStream.close(); catch (IOException ex) {// 接上protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { // 解析xml文件为Document Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); catch (BeanDefinitionStoreException ex) { // 省略代码// 接上 public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); // 从reader中注册BeanDefinition到工厂 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
DefaultBeanDefinitionDocumentReader#registerBeanDefinitions

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions。注册BeanDefinition对象。

 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug( Loading bean definitions  Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); // 接上 通过委托模式和模板模式来解析xml  protected void doRegisterBeanDefinitions(Element root) { BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); // 省略代码.... preProcessXml(root); //只关注此代码 parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent;//接上 只关注Spring自带的解析 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { 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)) { // Spring自带的标签解析 parseDefaultElement(ele, delegate); else { delegate.parseCustomElement(ele); else { delegate.parseCustomElement(root); //接上 支持解析Import标签、alias 、bean、beans嵌套的 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { //示例中应关注此处解析bean标签 processBeanDefinition(ele, delegate); else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); //接上 处理BeanDefinition protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { // 核心解析步骤(使用委托模式) BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 注册最终的装饰实例 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); catch (BeanDefinitionStoreException ex) { getReaderContext().error( Failed to register bean definition with name + bdHolder.getBeanName() + , ele, ex); // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); }
BeanDefinitionParserDelegate#parseBeanDefinitionElement(Element)

org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element)。真正的xml转BeanDefinition逻辑代码。

 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return parseBeanDefinitionElement(ele, null); // 解析xml,生成AbstractBeanDefinition对象实例,交给AbstractBeanDefinition管理 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { String id = ele.getAttribute(ID_ATTRIBUTE); String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); List String aliases = new ArrayList String  //如果使用了name标签,将name作为别名 if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); String beanName = id; if (!StringUtils.hasText(beanName) !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug( No XML id specified - using + beanName + as bean name and + aliases + as aliases  if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); // 解析元素内容成BeanDefinition AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null  beanName.startsWith(beanClassName) beanName.length() beanClassName.length()  !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); if (logger.isDebugEnabled()) { logger.debug( Neither XML id nor name specified - + using generated bean name [ + beanName + ]  catch (Exception ex) { error(ex.getMessage(), ele); return null; String[] aliasesArray = StringUtils.toStringArray(aliases); //包装成BeanDefinitionHolder对象 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); return null; public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); try { String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); //创建基本的BeanDefinition对象,设置beanName,ParentName,ClassLoader等信息 AbstractBeanDefinition bd = createBeanDefinition(className, parent); //解析比如singleton、lazy-init、scope、abstract等等属性标签,并设置到BeanDefinition(以下简称为bd)实例中 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); // 解析description标签 设置到Bd对象中 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); // 解析meta标签 设置到bd对象中 parseMetaElements(ele, bd); // 解析lookup-method标签 设置到bd对象中 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); // 解析replaced-method标签 设置到bd对象中 parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); // 解析constructor-arg标签 设置到bd对象中 parseConstructorArgElements(ele, bd); // 解析property标签 设置到bd对象中(比如我们使用datasource时注入的url、user、pwd这些property) parsePropertyElements(ele, bd); // 解析qualifier标签 设置到bd对象中 parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); return bd; catch (ClassNotFoundException ex) { error( Bean class [ + className + ] not found , ele, ex); catch (NoClassDefFoundError err) { error( Class that bean class [ + className + ] depends on not found , ele, err); catch (Throwable ex) { error( Unexpected failure during bean definition parsing , ele, ex); finally { this.parseState.pop(); return null; protected AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.readerContext.getBeanClassLoader());org.springframework.beans.factory.support.BeanDefinitionReaderUtils#createBeanDefinition public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { GenericBeanDefinition bd = new GenericBeanDefinition(); bd.setParentName(parentName); if (className != null) { if (classLoader != null) { bd.setBeanClass(ClassUtils.forName(className, classLoader)); else { bd.setBeanClassName(className); return bd; }
返回到DefaultBeanDefinitionDocumentReader#processBeanDefinition

一层层调用返回,返回到org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition。我们继续分析BeanDefinitionReaderUtils.registerBeanDefinition部分。这个部分是真正把BeanDefiniton关联到当前Context中的步骤。

 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); catch (BeanDefinitionStoreException ex) { getReaderContext().error( Failed to register bean definition with name + bdHolder.getBeanName() + , ele, ex); // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); }
org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition

将Holder持有的BeanDefiniton交给BeanDefinitionRegistry(当前context也是个registry实例,是DefaultListableBeanFactory)持有

 public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); // 核心关注这块的逻辑 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); }
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

首次进入此方法,1. beanDefinition是AbstractBeanDefinition类型的实例,进行validate;2. oldBeanDefinition为空,执行else代码 3. BeanCreationStarted为false,执行beanDefinitionMap、beanDefinitionNames、manualSingletonNames值操作。

特别注意这几个对象(beanDefinitionMap、beanDefinitionNames、manualSingletonNames),后续实例化Bean、获取Bean时会用到
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, Bean name must not be empty  Assert.notNull(beanDefinition, BeanDefinition must not be null  // 如果是AbstractBeanDefinition类型实例 进行validate if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, Validation of bean definition failed , ex); BeanDefinition oldBeanDefinition; oldBeanDefinition = this.beanDefinitionMap.get(beanName); // 首次进入 old为空 if (oldBeanDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, Cannot register bean definition [ + beanDefinition + ] for bean + beanName + : There is already [ + oldBeanDefinition + ] bound.  else if (oldBeanDefinition.getRole() beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn( Overriding user-defined bean definition for bean + beanName + with a framework-generated bean definition: replacing [ + oldBeanDefinition + ] with [ + beanDefinition + ]  else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info( Overriding bean definition for bean + beanName + with a different definition: replacing [ + oldBeanDefinition + ] with [ + beanDefinition + ]  else { if (this.logger.isDebugEnabled()) { this.logger.debug( Overriding bean definition for bean + beanName + with an equivalent definition: replacing [ + oldBeanDefinition + ] with [ + beanDefinition + ]  this.beanDefinitionMap.put(beanName, beanDefinition); else { //首次为false if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List String updatedDefinitions = new ArrayList String (this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set String updatedSingletons = new LinkedHashSet String (this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; else { //仍处于启动注册阶段(即没有真正的实例化,只是将bean的属性定义拿到,还不可以直接使用。) // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); this.frozenBeanDefinitionNames = null; if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); }
SpringBean创建

在BeanDefiniton注入registry中后,一步步返回到 AbstractApplicationContext#refresh方法中,我们这里只关注基本的Bean实例化过程。

synchronized (this.startupShutdownMonitor) { try { // 主要是这个代码 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); }
AbstractApplicationContext#finishBeanFactoryInitializationorg.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

finishBeanFactoryInitialization。实例化BeanFactory持有的其他正常的非延迟加载的单例集合.。这里往下看“preInstantiateSingletons”方法

 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //省略代码.... // 实例化BeanFactory持有的其他正常的非延迟加载的单例集合 beanFactory.preInstantiateSingletons(); }
DefaultListableBeanFactory#preInstantiateSingletons

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons。创建Bean分为二种,一种是FactoryBean,一种是普通Bean。这里我们只分析普通Bean。

注意这里的 this.beanDefinitionNames 是“obtainFreshBeanFactory()”创建赋值的。即我们的StringUtils的BeanDefinition。
 List String beanNames = new ArrayList String (this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() bd.isSingleton() !bd.isLazyInit()) { if (isFactoryBean(beanName)) { final FactoryBean ? factory = (FactoryBean ? ) getBean(FACTORY_BEAN_PREFIX + beanName); boolean isEagerInit; if (System.getSecurityManager() != null factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged(new PrivilegedAction Boolean () { @Override public Boolean run() { return ((SmartFactoryBean ? ) factory).isEagerInit(); }, getAccessControlContext()); else { isEagerInit = (factory instanceof SmartFactoryBean  ((SmartFactoryBean ? ) factory).isEagerInit()); if (isEagerInit) { getBean(beanName); else { //我们重点关注的是这个地方哈 getBean(beanName); }
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

继续跟进就行

 public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
(单例)org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

这里我们就是要创建单例的实例(有就从缓存中取)。创建的方式是通过ObjectFactory内部类实现中的createBean方法来完成。我们先看下getSingleton的逻辑。

 // 首次进来为空 最后会走下边的逻辑 Object sharedInstance = getSingleton(beanName); // 通过this.beanDefinitionMap得到的 具体可自行查看源码。这里不太花篇幅讲述。 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //... if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory Object () { @Override public Object getObject() throws BeansException { try { //最终创建Bean的逻辑 return createBean(beanName, mbd, args); catch (BeansException ex) { destroySingleton(beanName); throw ex; bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); //....  // 注意这里,会把单例cache起来,在后边可以直接使用 if (newSingleton) { addSingleton(beanName, singletonObject); }
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory ? )

这里我们要分析的核心逻辑(instance singleton)是调用的了ObjectFactory.getObject,即我们上边的内部类,而内部类的实现则是通过createBean完成。我们再来看下createBean的逻辑。

 try { //回到了AbstractBeanFactory#doGetBean的ObjectFactory的getObject方法,执行其中的createBean方法 singletonObject = singletonFactory.getObject(); newSingleton = true; }
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

AbstractBeanFactory的子类实现方法

 AbstractAutowireCapableBeanFactory#createBean(java.lang.Class T ) public T T createBean(Class T beanClass) throws BeansException { // Use prototype bean definition, to avoid registering bean as dependent bean. RootBeanDefinition bd = new RootBeanDefinition(beanClass); bd.setScope(SCOPE_PROTOTYPE); bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader()); return (T) createBean(beanClass.getName(), bd, null);// 接上protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; Class ? resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null !mbd.hasBeanClass() mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); try { mbdToUse.prepareMethodOverrides(); catch (BeanDefinitionValidationException ex) { try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; catch (Throwable ex) { // 普通Bean的实例创建 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug( Finished creating instance of bean + beanName +  return beanInstance; }
AbstractAutowireCapableBeanFactory#doCreateBean

核心关注instanceWrapper和exposedObject对象的处理过程

 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); if (instanceWrapper == null) { //创建bean实例的Wrapper对象 instanceWrapper = createBeanInstance(beanName, mbd, args); // bean实例在wrapper中已经创建了(不完整) final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); //省略一些代码。。。 // Initialize the bean instance. Object exposedObject = bean; try { // 注入property到Bean中 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); //省略一些代码。。。 return exposedObject;
AbstractAutowireCapableBeanFactory#createBeanInstance

instanceWrapper = createBeanInstance(beanName, mbd, args); 该方法是给指定的name的Class创建Bean对象,支持无参、factoryMethod、AutoWireConstructor三种策略。默认执行无参的 instantiateBean

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. Class ? beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null !Modifier.isPublic(beanClass.getModifiers()) !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, Bean class isn t public, and non-public access not allowed: + beanClass.getName()); if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; // 一般我们不是FactoryMethod和有参构造(也可以有哈) if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); else { return instantiateBean(beanName, mbd); // Need to determine the constructor... Constructor ? [] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); //没有特殊处理就使用无参构造实例 // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); }
AbstractAutowireCapableBeanFactory#instantiateBean

通过“getInstantiationStrategy().instantiate(mbd, beanName, parent)”生成实例。

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged(new PrivilegedAction Object () { @Override public Object run() { return getInstantiationStrategy().instantiate(mbd, beanName, parent); }, getAccessControlContext()); else { // 一般会走这块代码逻辑来生成bean实例 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, Instantiation of bean failed , ex); }
SimpleInstantiationStrategy#instantiate

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)。 通过bd获取BeanDefinition中对应BeanName的Class构造方法实例,交给BeanUtils去实例化真正的bean对象

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { // Don t override the class with CGLIB if no overrides. if (bd.getMethodOverrides().isEmpty()) { Constructor ? constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor ? ) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class ? clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, Specified class is an interface  try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction Constructor ? () { @Override public Constructor ? run() throws Exception { return clazz.getDeclaredConstructor((Class[]) null); else { //获取xml中bean标签定义的Class的Constructor实例 constructorToUse = clazz.getDeclaredConstructor((Class[]) null); bd.resolvedConstructorOrFactoryMethod = constructorToUse; catch (Throwable ex) { throw new BeanInstantiationException(clazz, No default constructor found , ex); //实例化“xml中bean标签定义的Class” return BeanUtils.instantiateClass(constructorToUse); else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(bd, beanName, owner); }
返回到 AbstractAutowireCapableBeanFactory#doCreateBean方法

我们继续看exposedObject处理的内容。装载Bean的Property属性,initBean对象。我们着重看下initializeBean方法。

final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);Object exposedObject = bean; try { //装载比如Property属性 可以是其他Bean对象,也可能是String等基本属性。 具体见populateBean中的applyPropertyValues方法 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //初始化Bean对象 exposedObject = initializeBean(beanName, exposedObject, mbd); }
AbstractAutowireCapableBeanFactory#initializeBeanorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

初始化给定的Bean,(RootBeanDefinition为空时,执行BeanPost)执行wired的相关方法((BeanNameAware、BeanClassLoaderAware、BeanFactoryAware))、执行initMethod。比如InitializingBean#afterPropertiesSet();或者是自定义的init方法。

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction Object () { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); else { //执行wire的method(BeanNameAware、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); return wrappedBean; }
AbstractAutowireCapableBeanFactory#invokeInitMethods

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods。执行afterPropertiesSet方法。如果是自定义的init方法,就调用invokeCustomInitMethod。

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean (mbd == null || !mbd.isExternallyManagedInitMethod( afterPropertiesSet ))) { if (logger.isDebugEnabled()) { logger.debug( Invoking afterPropertiesSet() on bean with name + beanName +  if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction Object () { @Override public Object run() throws Exception { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); catch (PrivilegedActionException pae) { throw pae.getException(); else { ((InitializingBean) bean).afterPropertiesSet(); if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null !(isInitializingBean afterPropertiesSet .equals(initMethodName))  !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); }
返回 AbstractApplicationContext#refresh

至此Bean实例化完成。

 // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);
SpringBean获取

还是我们的例子,在我们返回的ApplicationContext实例中,有个getBean方法,接下来我们着重来看getBean的实现。

 //ApplicationContext context = new ClassPathXmlApplicationContext( classpath:/spring/test.xml  context.getBean(StringUtils.class);
AbstractApplicationContext#getBean
 public T T getBean(Class T requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(requiredType); }
DefaultListableBeanFactory#getBean(java.lang.Class T )

org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class T ) 。这里主要分析resolveNamedBean的源码逻辑。

 public T T getBean(Class T requiredType) throws BeansException { return getBean(requiredType, (Object[]) null); @Override public T T getBean(Class T requiredType, Object... args) throws BeansException { //获取NamedBeanHolder对象 核心获取SpringBean的逻辑 NamedBeanHolder T namedBean = resolveNamedBean(requiredType, args); if (namedBean != null) { //最后是这里返回实例 return namedBean.getBeanInstance(); BeanFactory parent = getParentBeanFactory(); if (parent != null) { return parent.getBean(requiredType, args); throw new NoSuchBeanDefinitionException(requiredType); //接上
DefaultListableBeanFactory#resolveNamedBean(java.lang.Class T , java.lang.Object...)

示例中的源码会执行 new NamedBeanHolder T (beanName, getBean(beanName, requiredType, args)) 。beanName=test.xml中定义的id,即 stringutil 。我们下边主要看下getBeanNamesForType和getBean方法的逻辑。

//requiredType= StringUtil args=nullprivate T NamedBeanHolder T resolveNamedBean(Class T requiredType, Object... args) throws BeansException { Assert.notNull(requiredType, Required type must not be null  // 根据Class类型获取名字 示例中只有一个[ stringutil ] String[] candidateNames = getBeanNamesForType(requiredType); if (candidateNames.length 1) { List String autowireCandidates = new ArrayList String (candidateNames.length); for (String beanName : candidateNames) { if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) { autowireCandidates.add(beanName); if (!autowireCandidates.isEmpty()) { candidateNames = StringUtils.toStringArray(autowireCandidates); // 我们示例中length==1 ,beanName=stringutil 和我们定义的id保持一致 if (candidateNames.length == 1) { String beanName = candidateNames[0]; //注意看下getBean方法的执行逻辑 return new NamedBeanHolder T (beanName, getBean(beanName, requiredType, args)); else if (candidateNames.length 1) { Map String, Object candidates = new LinkedHashMap String, Object (candidateNames.length); for (String beanName : candidateNames) { if (containsSingleton(beanName)) { candidates.put(beanName, getBean(beanName, requiredType, args)); else { candidates.put(beanName, getType(beanName)); String candidateName = determinePrimaryCandidate(candidates, requiredType); if (candidateName == null) { candidateName = determineHighestPriorityCandidate(candidates, requiredType); if (candidateName != null) { Object beanInstance = candidates.get(candidateName); if (beanInstance instanceof Class) { beanInstance = getBean(candidateName, requiredType, args); return new NamedBeanHolder T (candidateName, (T) beanInstance); throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); return null; }
DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class ? )

最后是使用在解析xml时(loadBeanDefinition时),从存在this.beanDefinitionNames集合中获取beanName。具体看下边 doGetBeanNamesForType 方法的源码。

 public String[] getBeanNamesForType(Class ? type) { return getBeanNamesForType(type, true, true); // type==StringUtil 不为空 public String[] getBeanNamesForType(Class ? type, boolean includeNonSingletons, boolean allowEagerInit) { if (!isConfigurationFrozen() || type == null || !allowEagerInit) { return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit); //cache为空 size==0 Map Class ? , String[] cache = (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType); String[] resolvedBeanNames = cache.get(type); if (resolvedBeanNames != null) { return resolvedBeanNames; // 会执行这里!!!! resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true); if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) { cache.put(type, resolvedBeanNames); return resolvedBeanNames;// 从this.beanDefinitionNames中获取beanNameprivate String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) { List String result = new ArrayList String  // Check all bean definitions. for (String beanName : this.beanDefinitionNames) { // Only consider bean as eligible if the bean name // is not defined as alias for some other bean. if (!isAlias(beanName)) { try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Only check bean definition if it is complete. if (!mbd.isAbstract() (allowEagerInit || (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())  !requiresEagerInitForType(mbd.getFactoryBeanName()))) { // In case of FactoryBean, match object created by FactoryBean. boolean isFactoryBean = isFactoryBean(beanName, mbd); BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); boolean matchFound = (allowEagerInit || !isFactoryBean || (dbd != null !mbd.isLazyInit()) || containsSingleton(beanName))  (includeNonSingletons || (dbd != null ? mbd.isSingleton() : isSingleton(beanName)))  isTypeMatch(beanName, type); if (!matchFound isFactoryBean) { // In case of FactoryBean, try to match FactoryBean instance itself next. beanName = FACTORY_BEAN_PREFIX + beanName; matchFound = (includeNonSingletons || mbd.isSingleton()) isTypeMatch(beanName, type); if (matchFound) { //最后会执行这里 result.add(beanName); catch (CannotLoadBeanClassException ex) { catch (BeanDefinitionStoreException ex) {

本文链接: http://newresource.immuno-online.com/view-770334.html

发布于 : 2021-03-25 阅读(0)