Spring Bean加载流程分析(通过 XML 方式加载)(11)
其实也是很简单 , 就是解析 bean 标签中的其他属性 , 分别为 createBeanDefinition 返回的 BeanDefinition 对象的属性赋值 。 可能有人有疑问了 , 我们在 bean 标签中并没有配置其他的属性 , 但是部分属性还是存在默认值的 。这里的属性定义其实就是跟 applicationContext.xml 中的 bean 标签是对应上的
文章插图
另外还有其他的两个方法我们要关心一下
/** * Parse constructor-arg sub-elements of the given bean element. * 解析 bean 标签中的子元素 constructor-arg 参数 */public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {NodeList nl = beanEle.getChildNodes();for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);if (isCandidateElement(node)}}}/** * Parse property sub-elements of the given bean element. * 解析 bean 标签中的 property 参数 */public void parsePropertyElements(Element beanEle, BeanDefinition bd) {NodeList nl = beanEle.getChildNodes();for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);if (isCandidateElement(node)}}}复制代码
至此 , 我们这里便返回了一个完整的 BeanDefinitionHolder 对象 。
文章插图
该 BeanDefinitionHolder 中包含了从 xml 文件中解析出来的 BeanDefinition 对象和 beanName 属性 。
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder) 该行就是对我们返回的 BeanDefinitionHolder 装饰一下 , 也就是看看是否需要添加其他额外的属性 , 最后返回依然是一个 BeanDefinitionHolder 对象 。
最后重头戏来了 , 通过了 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法向 registry 中注册了一个 BeanDefinitionHolder 对象 , 看看是如何注册的 。
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);}}}复制代码
重点在于我们调用了 registry 的 registerBeanDefinition 方法 , registerBeanDefinition 有多个实现 , 而显然我们应该查看 DefaultListableBeanFactory 的实现.
文章插图
@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {// 判断 BeanDefinition 是否是 AbstractBeanDefinition 的实例 , 显然这里是的 。 这里是只是对 beanDefinition 做了校验if (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition) beanDefinition).validate();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}// 从 beanDefinitionMap 中获取 BeanDefinition 的定义BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {// 判断是否有相同名称的 beanif (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);} else if (existingDefinition.getRole()
- 文件系统(02):基于SpringBoot管理Xml和CSV
- SpringBoot2.x入门到项目实战课程系列(第二章)
- SpringBoot集成Mybatis
- 大牛深入解析SpringBoot核心运行原理和运作原理源码
- SpringBoot写后端接口,看这一篇就够了
- 9款游戏13块SSD:测试固态硬盘对游戏加载速度影响有多大?
- Spring Boot 中 @EnableX 注解的驱动逻辑
- SpringBoot2.x入门到项目实战课程系列(第五章)
- SpringBoot整合JWT+Shiro
- 14 个 SpringMVC顶级技巧,随时用随时爽