spring源码解析之IOC核心体系结构

1.spring IOC核心体系结构

1.1 BeanFactory

Spring Bean的创建典型是工厂模式,这些Bean工厂(IOC容器)为管理对象间的依赖关系提供了便利和基础服务,Spring有许多IOC容器实现,相互关系如下:
在这里插入图片描述>最顶层接口类BeanFactory,定义IOC容器的基本功能规范。
它有三个子类:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。
上图最终的默认实现类是DefaultListableBeanFactory,它实现了所有接口。

为何定义这么多层次的接口?每个接口都有使用场合,为区分Spring内对象的传递和转化过程中,对对象的数据访问所做的限制。
eg.ListableBeanFactory接口:可列表,HierarchicalBeanFactory:有继承关系(每个Bean有可能有父Bean),AutowireCapableBeanFactory:自动装配规则。这四接口定义了Bean的集合、Bean之间的关系、以及Bean行为。

  • 最基本的IOC容器接口BeanFactory
//org.springframework.beans.factory.BeanFactory
public interface BeanFactory {
   
	/**使用转义符&来得到FactoryBean本身,用来区分通过容器获得FactoryBean本身和其产生的对象**/
	String FACTORY_BEAN_PREFIX = "&";

	//通过name来获取IOC容器指定的bean
	Object getBean(String name) throws BeansException;

	//根据名字和类型来得到bean实例,增加了类型安全验证机制
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	//通过类型获取bean实例
	<T> T getBean(Class<T> requiredType) throws BeansException;

	//增加更多获取的条件,同上方法
	Object getBean(String name, Object... args) throws BeansException;

	//判断IOC容器是否含有指定名字的bean
	boolean containsBean(String name);

	//查询指定名字的Bean是不是单例的Bean
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	//判断Bean是不是prototype类型的bean
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	//查询指定了名字的Bean的Class类型是否与指定类型匹配
	boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

	//获取指定名字bean的Class类型
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	//查询指定了名字的bean的所有别名,这些别名都是在BeanDefinition中定义的
	String[] getAliases(String name);
}

只定义IOC容器的基本行为,不关心Bean如何定义、加载。(类比我们只关心工厂产品,不关心生产流程)
工厂如何产生对象?看具体IOC容器实现——eg.XmlBeanFactory,ClasspathXmlApplicationContext等。
XmlBeanFactory实现最基本的IOC容器(可读取XML文件定义的BeanDefinition(XML文件中对bean的描述))。

  • 类比:XmlBeanFactory——容器中的屌丝,ApplicationContext——容器中的高帅富。

ApplicationContext一个高级IOC容器,除了提供IOC容器的基本功能外,还提供如下附加服务:

1.支持信息源,可实现国际化(MessageSource);
2.访问资源(ResourcePatternResolver);
3.支持应用事件(ApplicationEventPublisher)。

1.2 BeanDefinition

IOC容器管理各种Bean对象及其相互关系,Bean对象以BeanDefinition描述,其继承体系如下: 在这里插入图片描述
Bean解析过程非常复杂,功能很细,需被扩展很多,必须保证足够的灵活性。Bean的解析主要是对配置文件的解析。这个解析过程主要通过下图中的类完成:
在这里插入图片描述


2.IOC容器初始化

IOC容器初始化:BeanDefinition的资源定位、载入和注册。以ApplicationContext为例(XmlWebApplicationContext、ClasspathXmlApplicationContext等皆属该继承体系):
在这里插入图片描述
ApplicationContext允许上下文嵌套,通过保持父上下文可维持一个上下文体系。Bean可在上下文体系中查找:①检查当前上下文;②父上下文,逐级向上(为不同的Spring应用提供共享的Bean环境)。

2.1 XmlBeanFactory(屌丝IOC)流程
// org.springframework.beans.factory.xml.XmlBeanFactory 
public class XmlBeanFactory extends DefaultListableBeanFactory {
   
    // this传的是factory对象
	private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

	public XmlBeanFactory(Resource resource) throws BeansException {
   
		this(resource, null);
	}

	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
   
		super(parentBeanFactory);
		this.reader.loadBeanDefinitions(resource);
	}
}
  • 直观表达源码意图:定位、载入、注册的全过程
// 根据xml文件,创建resource资源对象(包含BeanDefinition信息)
ClassPathResource resource = new ClassPathResource("applicantion-context.xml");
// 创造DefaultListableBeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 创建读取器,用于载入BeanDefinition
// 需要BeanDefinition做为参数——会将读取的信息回调配置给factory
// XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this)中的this传的是factory
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// 执行载入的BeanDefinition方法,最后完成bean的载入和注册
// 完成后bean成功放置到IOC容器中
reader.loadBeanDefinitions(resource);
2.2 FileSystemXmlApplicationContext的IOC容器流程
2.2.1 高富帅版IOC解剖
// org.springframework.context.support.FileSystemXmlApplicationContext
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {
   
	this(configLocations, true, null);
}
// 实际调用构造函数
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {
   

	super(parent);
	setConfigLocations(configLocations);
	if (refresh) {
   
		refresh();
	}
}
2.2.2 设置资源加载器和资源定位

创建FileSystemXmlApplicationContext容器时,构造方法做两项重要工作:

①调用父类容器的构造方法(super(parent)方法)为容器设置好Bean资源加载器;
②调用父类AbstractRefreshableConfigApplicationContext的setConfigLocations(configLocations)方法设置Bean定义资源文件的定位路径。

通过追踪FileSystemXmlApplicationContext的继承体系,发现其父类的父类AbstractApplicationContext中初始化IOC容器所做的主要源码如下:

// org.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {
   
		// 静态初始化块,在整个容器创建过程中只执行一次
	static {
   
		// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
		// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
		// 为了避免应用程序在Weblogic8.1关闭时出现类加载异常加载问题,加载IOC容器关闭事件(ContextClosedEvent)类
		ContextClosedEvent.class.getName();
	}
	public AbstractApplicationContext() {
   
		this.resourcePatternResolver = getResourcePatternResolver();
	}

	// FileSystemXmlApp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值