Spring之IOC容器的加载过程
1.IOC容器的加载
1)Resource定位(容器寻找数据的过程)
2)载入(把用户定义好的bean表示成IOC容器内部的数据结构即:BeanDefinition)
3)注册(把载入的BeanDefinition注册到IOC容器)
1.1Bean的创建
bean是什么时候创建的?第一次getBean的时候
1)检查bean是否已经存在,根据beanName获取BeanDefinition,递归获取依赖bean,根据不同属性的bean调用方法创建bean(如Singleton的,Scope的,Property的)
doGetBean
2)检查循环引用,设置bean的属性
createBean
3)通过不同的方式创建bean,策略模式,默认SimpleInstantiationStrategy,提供两种实例化方式,一种是BeanUtils(使用JVM的反射功能),另外一种是Cglib(字节码生成类库)
createBeanInstance
4)属性注入如@Autowired等
属性注入populateBean
1.2 实例化Bean的策略
1.Cglib
1.3Bean创建流程
<bean id="testSpringBean" class="com.bkjk.cf.receivablesfinancing.service.TestSpringBean" init-method="init" destroy-method="destory"> <property name="propertyAge" value="343434"/> <property name="propertyName" value="zhanfdifjidfj"/> </bean>
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if (refresh) { this.refresh(); } }
public void refresh() throws BeansException, IllegalStateException { Object var1 = this.startupShutdownMonitor; synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); //这里在子类中启动refreshBeanFactory 的地方 ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { // 设置beanFactory的后置处理 this.postProcessBeanFactory(beanFactory); //bean注册容器 this.invokeBeanFactoryPostProcessors(beanFactory); //注册bean的后处理,在bean创建过程中调用 this.registerBeanPostProcessors(beanFactory); //对上下文消息进行初始化 this.initMessageSource(); //初始化上线文的事件机制 this.initApplicationEventMulticaster(); //初始化其他的特殊的bean this.onRefresh(); //检查监听bean,并向容器注册 this.registerListeners(); //实例化所有的(non-lazy-init)单件 this.finishBeanFactoryInitialization(beanFactory); //发布容器时间,结束Refresh过程 this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } //为防止容器占用资源,在异常中销毁前面已经生成的单件bean this.destroyBeans(); //重置‘active’标签 this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } }
//创建 BeanFactory 并载入BeanDefinition protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { this.refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); if (this.logger.isDebugEnabled()) { this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory); } return beanFactory; } protected final void refreshBeanFactory() throws BeansException { if (this.hasBeanFactory()) { this.destroyBeans(); this.closeBeanFactory(); } try { //创建beanFactory DefaultListableBeanFactory beanFactory = this.createBeanFactory(); beanFactory.setSerializationId(this.getId()); this.customizeBeanFactory(beanFactory); //载入bean入口 this.loadBeanDefinitions(beanFactory); Object var2 = this.beanFactoryMonitor; synchronized(this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException var5) { throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5); } }
//AbstractXmlApplicationContext // XmlBeanDefinitionReader 定位resource,XmlBeanDefinitionReader protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); this.initBeanDefinitionReader(beanDefinitionReader); this.loadBeanDefinitions(beanDefinitionReader); }
//IOC 容器加载的核心方法 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { //一:读取xml文件 InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //二:加载 beanefinition var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } return var5; } } protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { //一 1) 将xml文件转换为document Document doc = this.doLoadDocument(inputSource, resource); return this.registerBeanDefinitions(doc, resource); } } //一 2) 开始执行 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; this.logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); this.doRegisterBeanDefinitions(root); } protected void doRegisterBeanDefinitions(Element root) { this.preProcessXml(root); //三 解析Element 获取xml内容 this.parseBeanDefinitions(root, this.delegate); this.postProcessXml(root); this.delegate = parent; } //解析Element 得到node 判断node内容 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)) { //读取document的内容 this.parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } //四 判断xml中(document中节点的类型) private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, "import")) { this.importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, "alias")) { this.processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, "bean")) { /* 五 载入beanDefinition 这里只是读取<bean>中的设置的class的name, 然后载入到BeanDefinition中,只是做个记录,并不设计对象的实例化,对象的实例化是在依赖注入时完成的*/ this.processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, "beans")) { this.doRegisterBeanDefinitions(ele); } } //五 载入BeanDefinition 这里得到documentReader后,为具体的spring bean 解析准备了数据 protected void processBeanDefinition(Element ele, eanDefinitionParserDelegate delegate) { //具体处理了BeanDefinition交给 BeanDefinitionParserDelegate /* 具体将<bean>的内容进行解析,解析为spring 的BeanDefinition BeanDefinitionHolder是BeanDefinition对象的封装,封装了bean的名称和别 名,用他来完成 向IOC容器注册,得到的BeanDefinitionHolder是通过beanDefinitionParserDelegate 对 XML的元素的信息按照spring 的bean规则进行解析得到的*/ BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException var5) { this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5); } // BeanDefinition向IOC容器注册之后,发送消息 this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } } //载入BeanDefinition public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) { String id = ele.getAttribute("id"); String nameAttr = ele.getAttribute("name"); List<String> aliases = new ArrayList(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; "); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; if (!StringUtils.hasText(id) && !aliases.isEmpty()) { beanName = (String)aliases.remove(0); if (this.logger.isDebugEnabled()) { this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { this.checkNameUniqueness(beanName, aliases, ele); } //将xml的内置转换为spring的bean信息 AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean); } //对<bean>的内容进行解析,转换为spring的bean public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute("class")) { className = ele.getAttribute("class").trim(); } String parent = null; if (ele.hasAttribute("parent")) { parent = ele.getAttribute("parent"); } try { //生成需要的BeanDefinition对象,为BeanDefinition的载入做准备 AbstractBeanDefinition bd = this.createBeanDefinition(className, parent); //设置<bean>的attribute scope,init,destory 等 this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description")); //设置元数据 如 key ,value这样的 this.parseMetaElements(ele, bd); this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //解析<bean>构造函数 this.parseConstructorArgElements(ele, bd); //设置<bean>property元素 this.parsePropertyElements(ele, bd); this.parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(this.extractSource(ele)); AbstractBeanDefinition var7 = bd; return var7; } } finally { this.parseState.pop(); } return null; }
/注册 BeanDefinition public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { //获取bean的 名称 String beanName = definitionHolder.getBeanName(); //注册bean 并将bean放入到ioc容器里面 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); if (aliases != null) { String[] var4 = aliases; int var5 = aliases.length; for(int var6 = 0; var6 < var5; ++var6) { String alias = var4[var6]; //注册其他信息 是否是单例,是否允许重载 是否是abstract 类 registry.registerAlias(beanName, alias); } } } //DefaultListableBeanFactory 具体执行注册的 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"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition)beanDefinition).validate(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9); } } //bean 已经存在 BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { //不允许覆盖 报异常 if (!this.isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + existingDefinition + "] bound."); } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (this.hasBeanCreationStarted()) { Map var4 = this.beanDefinitionMap; //synchronized,保证数据一致性 synchronized(this.beanDefinitionMap) { //将bean放入容器 this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || this.containsSingleton(beanName)) { this.resetBeanDefinition(beanName); } }
2.BeanDefinition是什么?
是一个接口,里面定义了一些bean的元数据,如beanName,score等,是对xml中<bean>的抽象
3.类图
4.面试题
BeanFactoryPostProcessor
修改BeanDefinition信息,修改bean的元信息,此时Bean还未初始化
自定义BeanFactoryPostProcessor
MyBeanFactoryPostProcessor
BeanPostProcessor
是在Bean创建完成,属性填充完之后执行的
initializeBean中调用BeanPostProcessor
自定义BeanPostProcessor
MyBeanPostProcessor