16. spring-容器: 探索BeanFactory-XmlBeanFactory, DefaultListableBeanFactory, XmlBeanDefinitionReader

BeanFactory

BeanFactory是所有Spring容器的根接口,提供了基本的容器操作方法,定义如下:


package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

public interface BeanFactory {

	String FACTORY_BEAN_PREFIX = "&";


	Object getBean(String name) throws BeansException;

	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * <p>Allows for specifying explicit constructor arguments / factory method arguments,
	 * overriding the specified default arguments (if any) in the bean definition.
	 * @since 2.5
	 */
	Object getBean(String name, Object... args) throws BeansException;

	/**
	 * Return the bean instance that uniquely matches the given object type, if any.
	 * @since 3.0
	 * @see ListableBeanFactory
	 */
	<T> T getBean(Class<T> requiredType) throws BeansException;

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * <p>Allows for specifying explicit constructor arguments / factory method arguments,
	 * overriding the specified default arguments (if any) in the bean definition.
	 * @since 4.1
	 */
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	/**
	 * Return a provider for the specified bean, allowing for lazy on-demand retrieval
	 * of instances, including availability and uniqueness options.
	 * @param requiredType type the bean must match; can be an interface or superclass
	 * @return a corresponding provider handle
	 * @since 5.1
	 * @see #getBeanProvider(ResolvableType)
	 */
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	/**
	 * @since 5.1
	 */
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);


	boolean containsBean(String name);

	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	/**
	 * Check whether the bean with the given name matches the specified type.
	 * More specifically, check whether a {@link #getBean} call for the given name
	 * would return an object that is assignable to the specified target type.
	 * @since 4.2
	 * @see #getBean
	 * @see #getType
	 */
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	/**
	 * @since 5.2
	 */
	@Nullable
	Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;


	String[] getAliases(String name);

}

总结下来有如下信息:

  • 是所有spring容器的根接口,提供基本的容器访问功能,更具体的接口参考ListableBeanFactory和ConfigurableBeanFactory

  • BeanFactory的实例会持有若干个BeanDefinition,即Bean的元信息(如bean name,类型,属性值,是否singleton等)。依据这些元信息会生产prototype实例或单例。

  • BeanFactory是组件的注册中心。

  • BeanFactory可以从XML,@ComponentScan, 甚至java代码加载BeanDefinition

  • 所有的BeanFactory实现需要尽可能的支持标准Bean生命周期。完整的初始化方法顺序如下:

    • BeanNameAware’s setBeanName
    • BeanClassLoaderAware’s setBeanClassLoader
    • BeanFactoryAware’s setBeanFactory
    • EnvironmentAware’s setEnvironment
    • EmbeddedValueResolverAware’s setEmbeddedValueResolver
    • ResourceLoaderAware’s setResourceLoader (only ApplicationContext容器)
    • ApplicationEventPublisherAware’s setApplicationEventPublisher(only ApplicationContext容器)
    • MessageSourceAware’s setMessageSource(only ApplicationContext容器)
    • ApplicationContextAware’s setApplicationContext(only ApplicationContext容器)
    • ServletContextAware’s setServletContext(only web ApplicationContext容器)
    • BeanPostProcessors’s postProcessBeforeInitialization
    • InitializingBean’s afterPropertiesSet
    • a custom init-method definition
    • BeanPostProcessors’s postProcessAfterInitialization

    在BeanFactory shutdown时,bean的销毁生命周期得到执行:

    • DestructionAwareBeanPostProcessors’s postProcessBeforeDestruction

    • DisposableBean’s destroy

    • a custom destroy-method definition

    • 核心方法是 getBean。 即根据bean name 或类型从容器中获取目标Bean实例。

    • 本接口应该是spring生态的祖宗,最早的版本从2001年4月13日开始 ^_^

BeanFactory是基础的IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟加载策略(Lazy-load)。即当需要访问容器中某个受管对象时,才对该组件进行初始化以及依赖注入操作。

特点:启动快,所需资源少,对于资源受限,要求功能少的场合,比较适用。

XmlBeanFactory

XmlBeanFactory是一个具体的spring容器,用于从xml文件中加载BeanDefinition。

源代码如下:

public class XmlBeanFactory extends DefaultListableBeanFactory {

	private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);


	/**
	 * Create a new XmlBeanFactory with the given resource,
	 * which must be parsable using DOM.
	 * @param resource the XML resource to load bean definitions from
	 * @throws BeansException in case of loading or parsing errors
	 */
	public XmlBeanFactory(Resource resource) throws BeansException {
		this(resource, null);
	}

	/**
	 * Create a new XmlBeanFactory with the given input stream,
	 * which must be parsable using DOM.
	 * @param resource the XML resource to load bean definitions from
	 * @param parentBeanFactory parent bean factory
	 * @throws BeansException in case of loading or parsing errors
	 */
	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
		super(parentBeanFactory);
		this.reader.loadBeanDefinitions(resource);
	}

}

从源码看XmlBeanFactory非常简单,就是有一个成员变量XmlBeanDefinitionReader, 然后本身继承了DefaultListableBeanFactory基类。

从外部XML文件加载BeanDefinition委托给XmlBeanDefinitionReader实现,它加载并读取BeanDefinition定义,最后注册到IoC容器中。

继承的基类DefaultListableBeanFactory是Spring 容器默认的容器类,后续所有专用的spring 容器如:XmlBeanFactory, ClassPathXmlBeanFactory, XmlWebApplicationContext, AnnotationConfigApplicationContext多多少少都基于它实现,是需要重点研究的容器类。

所以,使用DefaultListableBeanFactory加XmlBeanDefinitionReader可以实现XmlBeanFactory的功能,示例代码如下:

package win.elegentjs.spring.ioc.beanfactory.xmlbeanfactory;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import win.elegentjs.spring.ioc.beans.Person;

@Slf4j
public class XmlBeanFactorySample {


    public static void main(String[] args) {
        // 使用XmlBeanFactory容器
        XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        Person p = beanFactory.getBean(Person.class);

        log.info("==> p: {}", p);

        // 使用DefaultListableBeanFactory容器结合XmlBeanDefinitionReader
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
        xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));

        p = factory.getBean(Person.class);

        log.info("==> p: {}", p);


    }
}

// result:
2021-06-09 11:51:09.744 [main] INFO  w.e.s.i.b.xmlbeanfactory.XmlBeanFactorySample-==> p: Person(name=liu, age=20)
2021-06-09 11:51:09.808 [main] DEBUG o.s.beans.factory.xml.XmlBeanDefinitionReader-Loaded 1 bean definitions from class path resource [applicationContext.xml]
2021-06-09 11:51:09.809 [main] DEBUG o.s.b.factory.support.DefaultListableBeanFactory-Creating shared instance of singleton bean 'person'
2021-06-09 11:51:09.809 [main] INFO  w.e.s.i.b.xmlbeanfactory.XmlBeanFactorySample-==> p: Person(name=liu, age=20)

可以看出完全等价,理解了XmlBeanFactory的实现实际是对DefaultListableBeanFactory和XmlBeanDefinitionReader的包装,接下来我们重点分析DefaultListableBeanFactory和XmlBeanDefinitionReader即可。

DefaultListableBeanFactory

DefaultListableBeanFactory是spring IoC容器的重点,它实现了ConfigurableListableBeanFactory和BeanDefinitionRegistry两个重要接口, 先看类结构图,如下:

在这里插入图片描述
类层级结构非常复杂,重点看下来就是由若干层抽象基类和若干接口组成。

DefaultListableBeanFactory是spring提供的最重要的IoC容器,几乎所有的容器类都基于它实现,如BeanFactory系列的ClassPathXmlBeanFactory, XmlBeanFactory, ApplicationContext系列的ClassPathXmlApplicationContext, XmlWebApplicationContext等。

所以弄清楚DefaultListableBeanFactory的结构和实现至关重要

ConfigurableListableBeanFactory

先看DefaultListableBeanFactory的两大重要接口之一:ConfigurableListableBeanFactory, 从名字可以看出来它又继承了两个接口,分别是:ConfigurableBeanFactory和ListableBeanFactory。 另外它本身额外增加了分析和修改BeanDefinition的功能和预实例化单例的功能。
它的类结构图如下:
在这里插入图片描述
下面进一步分析ConfigurableBeanFactory

ConfigurableBeanFactory

ConfigurableBeanFactory是一个基础接口,提供了除了BeanFactory接口外的方法,主要用于增强容器,如addBeanPostProcessor, registerScope, registerAlias等。

它的类结构图如下:
在这里插入图片描述
到这一个层次,类结构图就比较清晰了,它继承了HierarchicalBeanFactory和SingletonBeanRegistry接口。

HierarchicalBeanFactory表示容器有层级,可以设置和获取父容器。
SingletonBeanRegistry 表示手动直接注册bean实例到容器(不太常用)

ListableBeanFactory

说完了ConfigurableBeanFactory,再来看看ListableBeanFactory, 它提供了迭代容器中bean的功能。

在这里插入图片描述

小结

本节从总体结构上学习了XmlBeanFactory,分析了DefaultListableBeanFactory, XmlBeanDefinitionReader, ConfigurableListableBeanFactory等容器类,了解了他们各自的功能。下一节从源码跟踪XmlBeanFactory的容器启动阶段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值