Spring源码合集: Spring源码解析(一)IOC容器
前言
在开始分析Spring之前我们需要几项准备工作
- Spring源码环境搭建(方便做笔记和复习)
- 流程图工具(方便梳理源码调用流程,process on、xmind…)
- 耐心(记得第一次看加载BeanDefinition的时候给我整不会了,怎么这么多loadBeanDefinitions…)
本章我们要分析的是使用ClassPathXmlApplicationContext读取xml配置文件启动Spring的源码流程。在梳理流程之前,我们需要对Spring容器的继承结构有一个大致的认识(有一些读过Spring源码的小伙伴应该有这样一种感觉,为啥Spring源码跳来跳去的,往往一个方法要重载,重写多次,最后跟了很久才到真正干事的地方。我个人觉得这就是Spring源码很精髓的一个点,是对“面向对象”和“设计模式”一种精妙的运用。想要感受这种设计的妙处,Spring容器的继承结构是一个很好的出发点)。
BeanFactory继承结构
这里先给出BeanFactory的继承结构图。 下面列出我认为比较重要的接口,建议读者可以打开源码看一下这些接口。
BeanFactory 接口 Bean工厂的根接口,提供了获取单个Bean实例的基本方法(根据类型,名称…)
使用到的设计模式:
- 简单工厂模式
- 单例模式
- 原型模式(prototype 原型),生成多例对象时是通过序列化来进行深拷贝。
BeanFactory中的方法:
interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, 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;
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
ListableBeanFactory 接口
继承BeanFactory接口,提供了根据类型、名称,注解等获取Bean集合(多个bean,前面BeanFactory只支持获取单个bean)的方法。
比如:
interface ListableBeanFactory {
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
String[] getBeanNamesForType(@Nullable Class<?> type);
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
HierarchicalBeanFactory 接口
继承BeanFactory接口,允许以可配置的方式设置父级的工厂
interface HierarchicalBeanFactory {
@Nullable
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
}
AutowireCapableBeanFactory 接口
继承BeanFactory接口,autowire我们非常熟悉,这个接口主要用于自动装配Bean。
里面有一些很重要(熟悉,如果你看过bean创建流程源码的话)的方法:
interface AutowireCapableBeanFactory {
int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
<T> T createBean(Class<T> beanClass) throws BeansException;
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
Object initializeBean(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
void destroyBean(Object existingBean);
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}
ConfigurableBeanFactory 接口
继承HierarchicalBeanFactory,SingletonBeanRegistry,它的方法主要是对 Bean 工厂进行配置,主要是框架内部使用。
SingletonBeanRegistry提供对单例对象的一些操作。
ConfigurableListableBeanFactory 接口
它的特殊之处在于继承了ConfigurableBeanFactory,ListableBeanFactory ,AutowireCapableBeanFactory三个接口(也就是说它会拥有这个三个接口所拥有的功能,后面会看到DefaultListableBeanFactory就是继承这个接口的)。
ApplicationContext的继承结构
这是ApplicationContext的继承结构图。 ApplicationContext官方介绍:
为应用程序提供配置的中央接口。 在应用程序运行时,这是只读的,但如果实现类支持,可以重新加载(刷新refresh)。
ApplicationContext提供:
- 访问应用程序组件的Bean工厂方法。继承自{@link org.springframework.beans.factory.ListableBeanFactory}。
- 以通用方式加载文件资源的能力。继承自{@link org.springframework.core.io.ResourceLoader}接口。
- 向注册的侦听器发布事件的能力。继承自{@link ApplicationEventPublisher}接口。
- 能够解析消息,支持国际化。继承自{@link MessageSource}接口。
- 从父上下文继承。后代上下文中的定义将始终优先考虑。例如,这意味着单亲家长整个web应用程序都可以使用上下文,而每个servlet都有它自己的子上下文独立于任何其他servlet的子上下文。
除了标准的{@link org.springframework.beans.factory.BeanFactory}生命周期功能、ApplicationContext实现、检测和调用{@link ApplicationContextAware}bean以及{@link resourceLoaderware},{@link ApplicationEventPublisherAware}和{@link MessageSourceAware}bean。
这些内容都会在后面的源码中得到体现。
ConfigurableApplicationContext 提供一些SPI接口(会被大多数实现类实现)和一些来配置ApplicationContext的方法。(refresh方法就是在这个类中定义的,后面分析源码会提到)
AbstractApplicationContext 采用模板方法模式,里面定义了很多属性和抽象方法,抽象方法需要子类实现。
FileSystemXmlApplicationContext 构造函数需要一个 xml 配置文件在系统中的路径,其他和 ClassPathXmlApplicationContext 基本上一样。
AnnotationConfigApplicationContext 基于注解来使用的,它不需要配置文件,采用 java 配置类和各种注解来配置。
容器启动流程分析
创建BeanFactory,加载注册Bean
准备BeanFactory
初始化所有单例Bean
Bean的生命周期
实例化对象
设置对象属性
检查Aware接口并设置相关依赖
BeanPostProcessor前置处理
InitializingBean接口
检查是否配置自定义的init-method
BeanPostProcessor后置处理
DisposableBean接口和destroy方法
总结
参考资料
|