Spring Ioc 源码分析(一)--Spring Ioc容器的加载

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 1.目标:熟练使用spring,并分析其源码,了解其中的思想。这篇主要介绍spring ioc 容器的加载2.前提条件:会使用debug3.源码分析方法:Intellj idea debug 模式下源码追溯通过ClassPathXmlApplicationContext 进行xml 件的读取,从每个堆栈中读取程序的运行信息4.注意:由于Spring的类继承体系比较复杂,不能全部贴图,所以只将分析源码之后发现的最主要的类继承结构类图贴在下方。

1.目标:熟练使用spring,并分析其源码,了解其中的思想。这篇主要介绍spring ioc 容器的加载
2.前提条件:会使用debug
3.源码分析方法:Intellj idea debug 模式下源码追溯
通过ClassPathXmlApplicationContext 进行xml 件的读取,从每个堆栈中读取程序的运行信息
4.注意:由于Spring的类继承体系比较复杂,不能全部贴图,所以只将分析源码之后发现的最主要的类继承结构类图贴在下方。
5.关于Spring Ioc Demo:我们从demo入手一步步进行代码追溯。

1.Spring Ioc Demo


1.定义数据访问接口IUserDao.java

public interface IUserDao {  
    public void InsertUser(String username,String password);
}

2.定义IUserDao.java实现类IUserDaoImpl.java

public class UserDaoImpl implements IUserDao {    
    @Override    
    public void InsertUser(String username, String password) { 
        System.out.println("----UserDaoImpl --addUser----");    
    }
}

3.定义业务逻辑接口UserService.java

public interface UserService {    
    public void addUser(String username,String password);
}

4.定义UserService.java实现类UserServiceImpl.java

public class UserServiceImpl implements UserService {    
    private     IUserDao  userDao;    //set方法  
    public void  setUserDao(IUserDao  userDao) {        
        this.userDao = userDao;   
    }    
    @Override    
    public void addUser(String username,String password) { 
        userDao.InsertUser(username,password);    
    }
}

bean.xml配置文件

<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-3.0.xsd         ">  
 <!--id名字自己取,class表示他代表的类,如果在包里的话需要加上包名-->    
 <bean id="userService"  class="UserServiceImpl" >      
        <!--property代表是通过set方法注入,ref的值表示注入的内容-->
        <property  name="userDao"  ref="userDao"/>  
 </bean>    
  <bean id="userDao"  class="UserDaoImpl"/>
</beans>

2.ApplicationContext 继承结构:


1.顶层接口:ApplicationContext
2.ClassPathXmlApplicationContext实现类继承AbstractXmlApplication 抽象类
3.AbstractXmlApplication 继承AbstractRefreshableConfigApplicationContext
4.AbstractRefreshableConfigApplicationContext抽象类继承AbstractRefreshableApplicationContext
5.AbstractRefreshableApplicationContext 继承 AbstractApplicationContext
6.AbstractApplicationContext 实现ConfigurableApplicationContext 接口
7.ConfigurableApplicationContext 接口继承
ApplicationContext接口
总体来说继承实现结构较深,内部使用了大量适配器模式。
以ClassPathXmlApplicationContext为例,继承类图如下图所示:


img_3c45e5e72807d6477280c3c400aa2156.png
Spring ioc .png

3.Spring Ioc容器加载过程源码详解


在开始之前,先介绍一个整体的概念。即spring ioc容器的加载,大体上经过以下几个过程:
资源文件定位、解析、注册、实例化

1.资源文件定位
其中资源文件定位,一般是在ApplicationContext的实现类里完成的,因为ApplicationContext接口继承ResourcePatternResolver 接口,ResourcePatternResolver接口继承ResourceLoader接口,ResourceLoader其中的getResource()方法,可以将外部的资源,读取为Resource类。


2.解析DefaultBeanDefinitionDocumentReader,
解析主要是在BeanDefinitionReader中完成的,最常用的实现类是XmlBeanDefinitionReader,其中的loadBeanDefinitions()方法,负责读取Resource,并完成后续的步骤。ApplicationContext完成资源文件定位之后,是将解析工作委托给XmlBeanDefinitionReader来完成的
解析这里涉及到很多步骤,最常见的情况,资源文件来自一个XML配置文件。首先是BeanDefinitionReader,将XML文件读取成w3c的Document文档。
DefaultBeanDefinitionDocumentReader对Document进行进一步解析。然后DefaultBeanDefinitionDocumentReader又委托给BeanDefinitionParserDelegate进行解析。如果是标准的xml namespace元素,会在Delegate内部完成解析,如果是非标准的xml namespace元素,则会委托合适的NamespaceHandler进行解析最终解析的结果都封装为BeanDefinitionHolder,至此解析就算完成。
后续会进行细致讲解。


3.注册
然后bean的注册是在BeanFactory里完成的,BeanFactory接口最常见的一个实现类是DefaultListableBeanFactory,它实现了BeanDefinitionRegistry接口,所以其中的registerBeanDefinition()方法,可以对BeanDefinition进行注册这里附带一提,最常见的XmlWebApplicationContext不是自己持有BeanDefinition的,它继承自AbstractRefreshableApplicationContext,其持有一个DefaultListableBeanFactory的字段,就是用它来保存BeanDefinition
所谓的注册,其实就是将BeanDefinition的name和实例,保存到一个Map中。刚才说到,最常用的实现DefaultListableBeanFactory,其中的字段就是beanDefinitionMap,是一个ConcurrentHashMap。
代码如下:
>1.DefaultListableBeanFactory继承实现关系

public class DefaultListableBeanFactory
extends 
AbstractAutowireCapableBeanFactory   
implements
ConfigurableListableBeanFactory, 
BeanDefinitionRegistry,
Serializable { 
     // DefaultListableBeanFactory的实例中最终保存了所有注册的bean    beanDefinitionMap
     /** Map of bean definition objects, keyed by bean name */
     private final Map<String, BeanDefinition> beanDefinitionMap 
     = new ConcurrentHashMap<String, BeanDefinition>(64); 
     //实现BeanDefinitionRegistry中定义的registerBeanDefinition()抽象方法
     public void registerBeanDefinition(String beanName, BeanDefinition    beanDefinition)      throws BeanDefinitionStoreException {
     }

>2.BeanDefinitionRegistry接口

public interface BeanDefinitionRegistry extends AliasRegistry {   
    //定义注册BeanDefinition实例的抽象方法
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)         throws BeanDefinitionStoreException;

4.实例化


注册也完成之后,在BeanFactory的getBean()方法之中,会完成初始化,也就是依赖注入的过程
大体上的流程就是这样,下一篇博客,再具体地从代码层面进行介绍。

博客搬家:大坤的个人博客
欢迎评论哦~

目录
相关文章
|
1月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
1月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
336 2
|
5月前
|
XML 人工智能 Java
Spring IOC 到底是什么?
IOC(控制反转)是一种设计思想,主要用于解耦代码,简化依赖管理。其核心是将对象的创建和管理交给容器处理,而非由程序直接硬编码实现。通过IOC,开发者无需手动new对象,而是由框架负责实例化、装配和管理依赖对象。常见应用如Spring框架中的BeanFactory和ApplicationContext,它们实现了依赖注入和动态管理功能,提升了代码的灵活性与可维护性。
189 1
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
6月前
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
|
8月前
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
9月前
|
XML Java 数据格式
Spring容器的本质
本文主要讨论Spring容器最核心的机制,用最少的代码讲清楚Spring容器的本质。
|
3月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
764 109