文档章节

Spring核心源码

陈孝杰
 陈孝杰
发布于 2017/06/19 10:52
字数 589
阅读 94
收藏 0

一、常见的初始化方式

spring常见的初始化方式有如下几种:

1. main函数里使用ClassPathXmlApplicationContext

public static void main(String[] args) {
    ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath*:/spring/test/appcontext-dependencies.xml");
    Thread.currentThread().join();
}

2. web.xml通过ContextLoaderListener

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/test/appcontext-dependencies.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

3. web.xml通过DispatcherServlet

<servlet>
    <servlet-name>springDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:config/spring/common/appcontext-*.xml,
            classpath*:config/spring/local/appcontext-*.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springDispatcher</servlet-name>
    <url-pattern>/study/*</url-pattern>
</servlet-mapping>

4. spring-test通过SpringJUnit4ClassRunner

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/spring/test/appcontext-dependencies.xml"})

5. spring4.x通过groovy dsl

import org.hibernate.validator.HibernateValidator
import org.springframework.context.support.ReloadableResourceBundleMessageSource
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean

beans {
    xmlns context: "http://www.springframework.org/schema/context"
    xmlns mvc: "http://www.springframework.org/schema/mvc"

    context.'component-scan'('base-package': "com.chenxiaojie.spring4")
    mvc.'annotation-driven'('validator': "validator")

    validator(LocalValidatorFactoryBean) {
        providerClass = HibernateValidator.class
        validationMessageSource = ref("messageSource")
    }
}

6. spring4.x通过全注解(http://jinnianshilongnian.iteye.com/blog/1991830)

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.chenxiaojie.spring4")
public class MvcConfiguration extends WebMvcConfigurationSupport {
    @Override
    protected Validator getValidator() {
        LocalValidatorFactoryBean localValidatorFactoryBean =
                new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
        localValidatorFactoryBean.setValidationMessageSource(messageSource());
        return localValidatorFactoryBean;
    }
}

 

二、初始化流程

无论是上方的哪一种初始化方式最后context初始化代码都是下方的refresh方法,这是典型的模板方法设计模式。

AbstractApplicationContext:

public void refresh() throws BeansException, IllegalStateException {

   // 同步块决定了spring的初始化一定是单线程的(spring作为bean容器默认只初始化一次, 多线程提高初始化速度并没有什么意义)
   synchronized (this.startupShutdownMonitor) {

      // 预准备refresh, 检查environment参数是否合理
      prepareRefresh();

      // 构造beanFactory, 里面包含所有beanDefinition加载, 主要是解析xml和注解
      // 参考AbstractRefreshableApplicationContext->refreshBeanFactory->loadBeanDefinitions方法
      // 参考AbstractBeanDefinitionReader->loadBeanDefinitions(String location, Set<Resource> actualResources)
      // 参考XmlBeanDefinitionReader->loadBeanDefinitions(EncodedResource encodedResource)
      // 参考DefaultBeanDefinitionDocumentReader->doRegisterBeanDefinitions(Element root)
      // 参考ContextNamespaceHandler->ComponentScanBeanDefinitionParser->parse->ClassPathBeanDefinitionScanner->doScan
      // 参考ClassPathScanningCandidateComponentProvider->findCandidateComponents(String basePackage)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 预准备beanFactory, 设置基本环境变量
      prepareBeanFactory(beanFactory);

      try {
         // 默认为空实现
         postProcessBeanFactory(beanFactory);

         // 添加实现了PriorityOrdered优先级极高的处理器, 这个环节只走半生命周期, 因为在new的时候postProcessors还未初始化完毕
         // org.springframework.context.annotation.internalConfigurationAnnotationProcessor
         invokeBeanFactoryPostProcessors(beanFactory);

         // 添加实现了Ordered的处理器,
         // org.springframework.context.annotation.internalAutowiredAnnotationProcessor
         // org.springframework.context.annotation.internalRequiredAnnotationProcessor
         // org.springframework.context.annotation.internalCommonAnnotationProcessor
         // org.springframework.aop.config.internalAutoProxyCreator
         // org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
         registerBeanPostProcessors(beanFactory);

         // 初始化消息
         initMessageSource();

         // 初始化事件处理器
         initApplicationEventMulticaster();

         // 默认空实现
         onRefresh();

         // 注册所有的spring监听器
         registerListeners();

         // 实现化所有业务相关的单例bean
         finishBeanFactoryInitialization(beanFactory);

         // 执行Lifecycle/事件通知等事务
         finishRefresh();
      }

      catch (BeansException ex) {
         // 销毁所有bean
         destroyBeans();

         cancelRefresh(ex);

         throw ex;
      }
   }
}

 

结构图

xml解析处理器

prepareBeanFactory给beanFactory实例化了三个bean

invokeBeanFactoryPostProcessors初始化实现了PriorityOrdered的处理器

registerBeanPostProcessors初始化实现了Ordered的处理器

 

© 著作权归作者所有

陈孝杰
粉丝 4
博文 6
码字总数 5639
作品 0
武汉
程序员
私信 提问
Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密...

小致Daddy
2018/08/03
23.7K
1
spring boot框架学习5-spring boot的web开发(1)

本章节主要内容: 通过前面的学习,我们了解并快速完成了spring boot第一个应用。spring boot企业级框架,那么spring boot怎么读取静态资源?如js文件夹,css文件以及png/jpg图片呢?怎么自定...

中凯_凯哥java
2017/11/01
501
0
第四十九章:SpringBoot2.0新特性 - 你get到WebMvcConfigurer两种配置方式了吗?

初升级版本,在已经使用的系统内还是存在一些兼容性的问题,有很多变化!!!也存在一些过时的方法、配置文件信息以及类,我们在之前版本的中可以使用抽象类来处理相关的配置,由于版本最低支...

恒宇少年
2018/03/17
0
0
spring boot 1.5.4 入门和原理(二)

1 spring boot入门 1.1 环境准备 JDK 7及以上 eclipse开发工具 项目管理工具Maven 本文采用、RELEASE(或1.5.2.RELEASE)调试通过。 spring-boot相关项目源码, 码云地址:https://git.oschi...

wyait
2017/09/18
0
0
SpringBoot2 整合 SpringSecurity 框架,实现用户权限安全管理

本文源码:GitHub·点这里 || GitEE·点这里 一、Security简介 1、基础概念 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组...

知了一笑
09/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kafka实战(五) - 核心API及适用场景全面解析

1 四个核心API ● Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。 ● Consumer API 允许一个应用程序订阅一个或多个topic ,并且对发布给他们的流式数据进行处...

JavaEdge
40分钟前
9
0
实现线程的第三种方式——Callable & Future

Callable Runnable 封装一个异步运行的任务, 可以把它想象成为一个没有参数和返回值的异步方 法。Callable 与 Runnable 类似, 但是有返回值。Callable 接口是一个参数化的类型, 只有一 个...

ytuan996
今天
9
0
OSChina 周六乱弹 —— 不要摁F了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 : 朴树写的词曲都给人一种莫名的失落感,不过这首歌他自己却没有唱,换成赵传这种高音阶嘶喊的确很好,低沉但却有力,老男人的呐喊...

小小编辑
今天
11
0
Android Binder机制 - interface_cast和asBinder讲解

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面来讲解一下: interface_cast 下面根据下述ICameraClient例子进行分析...

天王盖地虎626
昨天
13
0
计算机实现原理专题--存储器的实现(二)

计算机实现原理专题--存储器的实现(一)中描述了一种可以记住输入端变化的装置。现需要对其功能进行扩充,我们将上面的开关定义为置位,下面的开关定义为复位,然后需要增加一个保持位,当保...

FAT_mt
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部