spring bean 的加载机制(源码分析)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: spring bean加载

       xml的读取应该是Spring的重要功能,因为Spring的大部分功能都是以配置做为切入点的。


       我们在静态代码块中读取配置文件可以这样做:

         

   //这样来加载配置文件    
   XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml")); 

       (1)XmlBeanFactory 继承 AbstractBeanDefinitionReader ,使用ResourceLoader 将资源文件路径转换为对应的Resource文件。

       (2)通过DocumentLoader 对 Resource 文件进行转换,将 Resource 文件转换为 Document 文件。

       (3)通过实现接口 BeanDefinitionDocumentReader 的 DefaultBeanDefinitionDocumentReader 类对Document 进行解析,并且使用 BeanDefinitionParserDelegate对Element进行解析。


step1:



     在平常开发中,我们也可以使用Resource 获取 资源文件:


  Resource resource = new ClassPathResource("application.xml");
  InputStream in = resource.getInputStream();

  

step2:



      在资源实现加载之前,调用了 super(parentBeanFactory) --  /**Ignore the given dependency interface for autowiring.(忽略接口的自动装配功能)*/

      调用XmlBeanDefinitionReader 的 loadBeanDefinitions()方法进行加载资源:

      (1) 对Resource资源进行编码

      (2) 通过SAX读取XML文件来创建InputSource对象

      (3) 核心处理


     

       可以很直观的看出来是这个function是在解析xml文件从而获得对应的Document对象。


      在doLoadDocument方法里面还存一个方法getValidationModeForResource()用来读取xml的验证模式。(和我关心的没什么关系,暂时不看了~)


      转换成document也是最常用的方法:

    



step3 : 我们已经step by step 的看到了如何将xml文件转换成Document的,现在就要分析是如何提取和注册bean的。

            /**Register the bean definitions contained in the given DOM document*/



参数doc是doLoadBeanDefinitions()方法传进来的  loadDocument 加载过来的。这边就很好的体现出了面向对象的单一全责原则,将逻辑处理委托給单一的类去处理。

在这边单一逻辑处理类是:  BeanDefinitionDocumentReader


核心方法:  documentReader.registerBeanDefinitions(doc, createReaderContext(resource));


开始解析:


   

-------------


在Spring的xml配置中有两种方式来声明bean:

     一种是默认的:  <bean id = " " class = " " />

     还有一种是自定义的:  < tx : annotation-driven / >


通过xml配置文件的默认配置空间来判断:http://www.springframework.org/schema/beans


对于默认标签的解析:



对Bean 配置的解析:



BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);  返回BeanDefinitionHolder








这边代码大致看下来:

  1.   提取元素中的id和name属性
  2.   进一步解析将其他属性封装到 BeanDefinition 的实现类中
  3.   如果没有指定beanName 变使用默认规则生成beanName
  4. 封装类BeanDefinitionHolder


可以先了解一下  BeanDefinition  这个类的作用。

     

      BeanDefinition是一个接口,对应着配置文件中<bean>里面的所有配置,在Spring中存在着三个实现类:

      在配置文件中,可以定义父<bean>和子<bean>,父<bean>是用RootDefinition来表示,子<bean>是用ChildBeanDefinition来表示。

      Spring 通过BeanDefiniton将配置文件中的<bean>配置信息转换为容器内部表示,并且将这些BeanDefinition注册到BeanDefinitonRegistry中。

Spring容器的BeanDefinitonRegistry就像是Spring配置信息的内存数据库,主要是以map的形式保存的。


     因此解析属性首先要创建用于承载属性的实例:



然后就是各种对属性的解析的具体方法:








      









目录
相关文章
|
10天前
|
XML 安全 Java
|
24天前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
48 1
|
1月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
8天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
16 1
|
2月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
75 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
1月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
33 1
|
1月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
31 1
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
120 1
|
1月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
24 0