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的容器启动阶段。