您的位置:首页 > 编程语言 > Java开发

Spring:容器创建流程(源码解读)

2020-01-11 18:28 260 查看

一、前言

        Spring 容器,是 Spring 框架实现其两大核心思想:IoC、AOP的基础,平时我么可能只是会享受容器带给我们的便利,对容器的了解知之甚少。

        今天,我们通过 Spring 底层源码来分析 Spring 容器的构造过程,使我们对 Spring 的认识再上一个台阶,鉴于现在使用 Spring Boot 越来越多,在此将以 Servlet 类型的 AnnotationConfigServletWebServerApplicationContext 为例进行分析,对于Spring Boot 启动流程不太了解的,可以参考这里,其结构图如下:

二、容器初始化

        创建 AnnotationConfigServletWebServerApplicationContext,按照 Java 的语法规则会先行调用其父类的构造方法,然后才调用自身的构造函数进行对象的创建。

        在GenericApplicationContext中创建Spring IoC最重要的对象beanFactory。

public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}

        最后才会调用 AnnotationConfigServletWebServerApplicationContext 的构造函数完成 Spring 容器的创建和初始化工作。

public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
1) 创建 AnnotatedBeanDefinitionReader,用于对带注解的Bean类进行解析、注册
org.springframework.context.annotation.AnnotatedBeanDefinitionReader代码片段
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
//创建一个标准的环境对象StandardEnvironment
//如果是web应用,这个环境对象将是StandardServletEnvironment
//在SpringBoot项目中,该对象会被SpringBoot内核自动推断出来
this(registry, getOrCreateEnvironment(registry));
}

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
//用于对含有@Condition注解的类进行特殊解析
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//关键步骤,会注册用于解析相关注解的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
org.springframework.context.annotation.AnnotationConfigUtils代码片段
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//从registry也就是AnnotationConfigServletWebServerApplicationContext中获取之前注册到它身上的bean工厂。
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
/**
* 向Spring的beanFactory身上添加两个处理注解能力
* 1. AnnotationAwareOrderComparator是处理@oder和@Priority
* 2. ContextAnnotationAutowireCandidateResolver是处理@Lazy
*/
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* 以下是向bean工厂添加若干个Spring内部的配置类,这些配置类定义在org.springframework.context.annotation.AnnotationConfigUtils中
* 1.defaultListableBeanFactory.beanDefinitionMap中添加配置类的<name ,bd>
* 2.defaultListableBeanFactory.beanDefinitionNames中添加bd的name
*/
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
2) 创建 ClassPathBeanDefinitionScanner,

        还是老规矩,先构造父类,在调用子类构造方法完成创建和初始化工作。

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider代码片段
//定义了扫描resource文件的路径
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
private final List<TypeFilter> includeFilters = new LinkedList<>();
private final List<TypeFilter> excludeFilters = new LinkedList<>();
org.springframework.context.annotation.ClassPathBeanDefinitionScanner代码片段
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
//在scaner.includeFilters中添加javax.annotation.ManagedBean和javax.inject.Named两种注解类型filter
//@javax.annotation.ManagedBean是JAVA EE6自身提供的注解类
//@Inject、@Named、@Qualifier和@Provider是属于javax.inject.Named
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}

三、容器刷新

org.springframework.context.support.AbstractApplicationContext代码片段
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 为刷新做准备,设置启动时间和激活标识,初始化上下文中使用占位符的属性
prepareRefresh();
// 创建、初始化BeanFactory,加载、解析Bean的定义
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为BeanFactory填充功能,设置上下文的配置
prepareBeanFactory(beanFactory);
try {
// 子类扩展,对BeanFactory进行处理,此时所有Bean未被初始化
postProcessBeanFactory(beanFactory);
// 实例化、调用已注册的BeanFactoryPostProcessors#postProcessBeanFactory方法,用于修改BeanFactory
invokeBeanFactoryPostProcessors(beanFactory);
// 实例化,注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 初始化MessageSource,用于国际化处理
initMessageSource();
// 初始化应用事件广播器
initApplicationEventMulticaster();
// 子类扩展、初始化一些个性化Bean
onRefresh();
// 找到ApplicationListener bean,并注册
registerListeners();
// 初始化剩下的所有非lazy-init的单例Bean
finishBeanFactoryInitialization(beanFactory);
// 初始化LifecycleProcessor(生命周期处理器),发步对应的事件通知,如果配置了JMX,则注册MBean
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例Bean
destroyBeans();
// 重置active标记为false
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
子全 发布了22 篇原创文章 · 获赞 0 · 访问量 631 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: