Srping IOC运行时序解析

1.什么是SpringD的IOC与DI

IOC(Inversion Of Control)控制反转,所谓控制反转,就是把我们代码中需要实现的对象的创建过程交给容器来实现。同时需要一种描述让容器知道需要创建的对象和对象之间的关系,即配置文件。

DI (Dependency Injection) 依赖注入
依赖注入就是指对象被动接受依赖的类而不是自己主动去找,也就是,容器在实例化对象的时候主动将它依赖的类注入给它。

2. Spring核心容器类图

在了解IOC容器初始化之前,我们需要考虑以下几个问题:

  1. 对象和对象之间的关系如何表示?

xml properties文件等语义化配置文件表示

  1. 描述对象关系的文件存在哪里

classpath filesystem URL网络资源 servletContext等

  1. 不同的配置文件对对象的描述不一样,对标准的,自定义声明的,如何进行统一的描述?

在容器内部需要对对象的定义有一个统一的描述,所有外部的描述都必须转化成统一的描述定义

  1. 如何对不同的配置文件进行解析

对不同的配置文件,采用不同的解析器;

2.1 BeanFactory

在这里插入图片描述
BeanFactory:顶层接口类,定义了IOC容器的基本规范。
三个重要子类:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory,最终的默认实现类:DefaultListableBeanFactory,Spring内部在操作过程中对象的传递和转化过程中,有这各自的职能。如ListableBeanFactory接口,表示可初始化列表Bean

public interface BeanFactory { 
	//对 FactoryBean 的转义定义,因为如果使用 bean 的名字检索 FactoryBean 得到的对象是工厂生成的对象, 
	//如果需要得到工厂本身,需要转义 
	String FACTORY_BEAN_PREFIX = "&"; 
	//根据 bean 的名字,获取在 IOC 容器中得到 bean 实例
	Object getBean(String name) throws BeansException; 
	//根据 bean 的名字和 Class 类型来得到 bean 实例,增加了类型安全验证机制。 
	<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException; 
	Object getBean(String name, Object... args) throws BeansException; 
	<T> T getBean(Class<T> requiredType) throws BeansException; 
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException; 
	//提供对 bean 的检索,看看是否在 IOC 容器有这个名字的bean 
	boolean containsBean(String name); 
	//根据 bean 名字得到 bean 实例,并同时判断这个 bean 是不是单例 
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException; 
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException; 
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; 
	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException; 
	
	//得到 bean 实例的 Class 类型 
	@Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException; 
	//得到 bean 的别名,如果根据别名检索,那么其原名也会被检索出来 
	String[] getAliases(String name); 
}

在 BeanFactory 里只对 IOC 容器的基本行为作了定义,根本不关心你的 Bean 是如何定义怎样加载的。 正如我们只关心工厂里得到什么的产品对象,至于工厂是怎么生产这些对象的,这个基本的接口不关心。 而要知道工厂是如何产生对象的,我们需要看具体的 IOC 容器实现,Spring 提供了许多 IOC 容器 的 实 现 。 比 如 GenericApplicationContext , ClasspathXmlApplicationContext 等 。 ApplicationContext 是 Spring 提供的一个高级的 IOC 容器,它除了能够提供 IOC 容器的基本功能 外,还为用户提供了以下的附加服务。
从 ApplicationContext 接口的实现,我们看出其特点:
1、支持信息源,可以实现国际化。(实现 MessageSource 接口)
2、访问资源。(实现 ResourcePatternResolver 接口,后面章节会讲到)
3、支持应用事件。(实现 ApplicationEventPublisher 接口)

2.2 BeanDefinition

SpringIOC 容器管理了我们定义的各种 Bean 对象及其相互的关系,Bean 对象在 Spring 实现中是 以 BeanDefinition 来描述的,其继承体系如下:
在这里插入图片描述

2.3 BeanDefinitionReader

Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵 活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。这个解析过程主要通过 BeanDefintionReader 来完成,最后看看 Spring 中 BeanDefintionReader 的类结构图:在这里插入图片描述

3.IOC容器初始化过程

们知道Spring的初始化是从DispatcherServlet开始的,我们可以发现Spring中有许多init开头的方法,顾名思义,这些方法就是为Spring初始化做准备的。通过其继承关系,我们可以在其父类中找到最初的init()方法。在 SpringMVC运行时序图解析
一文中,我们知道 Servlet的 init() 方法中初始化了IOC容器和SpringMVC的九大组件,那么怎么才能找到IOC流程初始化的入口呢? ClassPathXmlApplicationContext 我们都用过:

ApplicationContext app = new ClassPathXmlApplicationContext("application.xml");

它的构造函数如下

public ClassPathXmlApplicationContext(String configLocation) throws BeansException { 
	this(new String[]{configLocation}, true, (ApplicationContext)null); 
}

但是它内部是调用如下这个构造函数的:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { 
	super(parent); 
	this.setConfigLocations(configLocations); 
	if(refresh) { 
		this.refresh(); 
	} 
}

根据setConfigLocations(configLocations); 这个方法,就可以跟踪IOC的初始化过程了:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值