Spring源码系列:BeanFactory的创建

栏目: Java · 发布时间: 6年前

内容简介:Spring源码系列:BeanFactory的创建

Spring的Ioc容器其实就是一个bean的关系网,依赖于core,bean,context三个组件来构建的。在spring中最核心的就是对于bean的管理。而bean又依托于我们的容器。本文将从顶层分析一下spring中beanFactory的具体创建过程,为后续的bean的生命周期提供一个基础。

BeanFactory的继承体系

Spring源码系列:BeanFactory的创建

从上图可以看到,BeanFactory有三个子类:

  • ListableBeanFactory
  • HierarchicalBeanFactory
  • AutowireCapableBeanFactory

(上述三个类的子类体系小伙伴们可以自己对着源码看下,实在太多)

看下上图中最底层的DefaultListableBeanFactory类的定义:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
	implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable

这个其实就是BeanFactory的默认实现类,它直接或者间接的实现了所有的接口。其实在看spring源码的时候都会遇到类似的设计模式,对于某一个具体的功能,通常都会定义很多层的接口,层层包装,层层委托。这种做法的好处就是,对于不同的场合都会有特定的接口;这样一来就可以在spring内部对对象的传递和转化操作都会有一些访问限制。

例如ListableBeanFactory接口表示这些Bean是可列表的,而HierarchicalBeanFactory表示的是这些Bean是有继承关系的,也就是每个Bean有可能有父Bean。AutowireCapableBeanFactory接口定义Bean的自动装配规则。这四个接口共同定义了Bean的集合、Bean之间的关系、以及Bean行为。

BeanFactory的创建

在之前的文章中说过了容器的刷新过程。BeanFactory的创建也在wac.refresh()方法中。具体看下到底是通过哪些子类来完成的:

// 通知子类刷新内部的bean工厂。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

1.AbstractApplicationContext中的obtainFreshBeanFactory

下面是obtainFreshBeanFactory的方法逻辑:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //这个是具体创建的方法,由子类实现
	refreshBeanFactory();
	//获取BeanFactory实例对象(ConfigurableListableBeanFactory类型的)
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}

refreshBeanFactory并未有具体的实现逻辑,这个方法主要是通过委托给子类的refreshBeanFactory方法来实现,在AbstractApplicationContext中refreshBeanFactory是一个抽象模板方法:

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

2.refreshBeanFactory方法(AbstractRefreshableApplicationContext类中):

下面只注释与beanFactory创建相关的代码

protected final void refreshBeanFactory() throws BeansException {
    //是否已经有BeanFactory了
    if (hasBeanFactory()) {
        //销毁原有的Bean
    	destroyBeans();
    	//关闭工厂
    	closeBeanFactory();
    }
    try {
        //创建一个新的beanFactory
    	DefaultListableBeanFactory beanFactory = createBeanFactory();
    	beanFactory.setSerializationId(getId());
    	customizeBeanFactory(beanFactory);
    	loadBeanDefinitions(beanFactory);
    	synchronized (this.beanFactoryMonitor) {
    		this.beanFactory = beanFactory;
    	}
    }
    catch (IOException ex) {
    	throw new ApplicationContextException("I/O error parsing bean definition 
    	source for " + getDisplayName(), ex);
    }
}

这个方法是实现执行这个上下文的底层bean工厂的实际刷新,如果有的话之前有BeanFactory存在,则关闭以前的bean工厂。并为上下文生命周期的下一个阶段初始化一个新鲜的bean工厂。

3.createBeanFactory(AbstractRefreshableApplicationContext类中)

protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

这个方法就是为当前上下文创建一个内部的bean工厂。每次调用refresh()方法是都会创建尝试创建。默认实现是创建一个DefaultListableBeanFactory。并通过getInternalParentBeanFactory()获取内部bean工厂来作为父级bean工厂。可以在子类中重写,例如自定义DefaultListableBeanFactory的设置。

getInternalParentBeanFactory(AbstractApplicationContext类中)

protected BeanFactory getInternalParentBeanFactory() {
	return (getParent() instanceof ConfigurableApplicationContext) ?
	((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
}

4.DefaultListableBeanFactory的构造函数

/**
 * 通过给定的父类创建一个新的DefaultListableBeanFactory容器
 * @param parentBeanFactory the parent BeanFactory
 */
public DefaultListableBeanFactory(BeanFactory parentBeanFactory) {
	super(parentBeanFactory);
}

super(parentBeanFactory)调用的是AbstractAutowireCapableBeanFactory的构造函数

/**
 * 通过给定的父类构建新的AbstractAutowireCapableBeanFactory
 * @param parentBeanFactory parent bean factory, or {@code null} if none
 */
public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
	this();
	//设置父工厂
	setParentBeanFactory(parentBeanFactory);
}

this(),还是AbstractAutowireCapableBeanFactory的构造函数:

/**
 * 构建一个新的AbstractAutowireCapableBeanFactory.
 */
public AbstractAutowireCapableBeanFactory() {
	super();
	ignoreDependencyInterface(BeanNameAware.class);
	ignoreDependencyInterface(BeanFactoryAware.class);
	ignoreDependencyInterface(BeanClassLoaderAware.class);
}

super() ; AbstractBeanFactory的构造函数

/**
 * 构建一个新的AbstractBeanFactory.
 */
public AbstractBeanFactory() {
}

以上所述就是小编给大家介绍的《Spring源码系列:BeanFactory的创建》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First HTML5 Programming(中文版)

Head First HTML5 Programming(中文版)

埃里克•弗里曼 (Eric Freeman)、伊丽莎白•罗布森 (Elisabeth Robson) / 中国电力出版社 / 2012-9 / 78.00元

《Head First HTML5 Programming(中文版)》内容简介:你可能想创建具有动态性、交互性、包含丰富数据而且互连的Web页面。先等一下,Web页面?为什么不用HTML5创建成熟的Web应用呢?另外,为什么不使用现代技术,像在移动设备上一样轻松地应用到桌面浏览器呢?当然,你肯定希望使用最新的HTML5技术来完成,比如地理定位、视频、2D绘制、Web存储、Web工作线程等,是不是?......一起来看看 《Head First HTML5 Programming(中文版)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具