- SpringBoot启动过程
- SpringApplication构造函数
- run(String...args)实例函数
- DefaultBootstrapContext
- ConfigurableEnvironment
- ConfigurableApplicationContext
- prepareContext
- postProcessApplicationContext
- applyInitializers
- DelegatingApplicationContextInitializer委托应用程序上下文初始化器
- SharedMetadataReaderFactoryContextInitializer共享元数据读取器工厂上下文初始化器
- ContextIdApplicationContextInitializer初始化上下文ID对象
- ConfigurationWarningsApplicationContextInitializer配置警告初始化对象
- RSocketPortInfoApplicationContextInitializer网络端口信息初始化对象
- ServerPortInfoApplicationContextInitializer服务器端口信息初始化对象
- ConditionEvaluationReportLoggingListener条件评估报告日志监听器
- getAllSources()
- load(context, sources.toArray(new Object[0]))
- refreshContext
- ServletWebServerApplicationContext
- AbstractApplicaitonContext.refresh() 刷新上下文
- prepareRefresh
- obtainFreshBeanFactory
- prepareBeanFactory(beanFactory)
- postProcessBeanFactory(beanFactory)
- invokeBeanFactoryPostProcessors(beanFactory)
- registerBeanPostProcessors(beanFactory)
- initMessageSource() 用于国际化
- initApplicationEventMulticaster() 为这个上下文初始化事件多播器。
- onRefresh() 在特定的上下文子类中初始化其他特殊bean 主题对象和创建webServer
- GenericWebApplicationContext.onRefresh()
- ServletWebServerApplicationContext.createWebServer
- TomcatServletWebServerFactory.getWebServer
- WebApplicationContext
- GenericWebApplicationContext.setServletContext
- ServletContextScope
- WebApplicationContextUtils.registerEnvironmentBeans 注册contextParameters、contextAttributes属性对象
- ServletContextInitializerBeans Servlet上下文初始化对象,触发sevletContext启动相关动作
- DispatcherServletRegistrationConfiguration$DispatcherServletRegistrationBean
- registerListeners检查并注册侦听器bean
- finishBeanFactoryInitialization实例化所有剩余的(非lazy-init)单例
- finishRefresh发布相应的事件
- afterRefresh(context, applicationArguments)空实现
参考代码
SpringBoot启动过程
@SpringBootApplication
@ImportResource(locations = {"dubbo-provider.xml"})
public class UserProviderBootstrap {
public static void main(String[] args) {
SpringApplication.run(UserProviderBootstrap.class,args);
}
}
SpringBoot应用启动,调用run方法,传入启动类,通过SpringApplication构造函数构造SpringApplication对象,然后调用run(String...)方法,返回ConfigurableApplicationContext对象。首先看一下构造函数做了哪些初始化动作。经过构造函数为SpringApplication对象赋值,继续调用SpringApplication的run(String...)方法。
SpringApplication构造函数
通过WebApplicationType.deduceFromClasspath()方式根据类路径下的信息来确定当前web应用类型;
调用getBootstrapRegistryInitializersFromSpringFactories()方法来获取启动注册的初始化对象,此处传入的类型为BootstrapRegistryInitializer,返回的对象列表为空。
getSpringFactoriesInstances(ApplicationContextInitializer.class)方法加载的对象由一下几个:
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
并赋值给成员变量initializers;
调用setListeners,加载并赋值监听器类
/**
*该类可以从java主方法引导和启动Spring应用程序。默认情况下,类将执行以下步骤来引导应用程序。
*1、创建一个适当的ApplicationContext实例(取决于你的类路径)
*2、注册一个命令行属性源,将命令行参数作为Spring属性公开
*3、刷新应用程序上下文,加载所有单例bean
*4、触发任何命令行运行器bean
*/
public class SpringApplication {
private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;
private List<ApplicationContextInitializer<?>> initializers;
private Class<?> mainApplicationClass;//mainApplicationClass = com.bail.user.service.UserProviderBootstrap
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
//资源加载器
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
//将主要类包装成LinkedHashSet集合类型,首要类,优先加载的资源
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();
//加载ApplicationContextInitializer类型为资源
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//推断应用主类,并赋值给mainApplicationClass变量
this.mainApplicationClass = deduceMainApplicationClass();
}
private Class<?> deduceMainApplicationClass() {
try {
//拿到运行栈数据,然后遍历,根据调用的方法名称是否为main获取到启动类主类,并返回类对象
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
}
总结:构造函数的功能主要是为成员变量赋值,包括首要类、确定web应用类型,从资源文件中加载的类资源,为注册初始类、监听器类、上下文初始化类赋值,确定主类
WebApplicationType
根据类路径包含的类信息返回web应用类型
WebApplicationType是一个枚举类
public enum WebApplicationType {
/**
* The application should not run as a web application and should not start an
* embedded web server.
*/
NONE,
/**
* The application should run as a servlet-based web application and should start an
* embedded servlet web server.
*/
SERVLET,
/**
* The application should run as a reactive web application and should start an
* embedded reactive web server.
*/
REACTIVE;
private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" };
static WebApplicationType deduceFromClasspath() {
//当当前类路径下面含有DispatcherHandler类时,并且没有DispatcherServlet类和ServletContainer类时,为REACTIVE类型web应用类型
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
//当类路径下面没有Servlet、和ConfigurableWebApplicationContext类时,应用不是一个Web类型服务器,且不可以启动一个内置的web服务器
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
//然后返回一个Servlet类型
return WebApplicationType.SERVLET;
}
}
getBootstrapRegistryInitializersFromSpringFactories
public class SpringApplication {
private List<BootstrapRegistryInitializer> getBootstrapRegistryInitializersFromSpringFactories() {
ArrayList<BootstrapRegistryInitializer> initializers = new ArrayList<>();
//根据Bootstrapper类型来获取Spring过程实例对象,并通过lambda转化成list集合
getSpringFactoriesInstances(Bootstrapper.class).stream()
.map((bootstrapper) -> ((BootstrapRegistryInitializer) bootstrapper::initialize))
.forEach(initializers::add);
initializers.addAll(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
return initializers;
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return getSpringFactoriesInstances(type, new Class<?>[] {});
}
//通过层层调用,我们发现底层使用了SpringFactoriesLoader.loadFactoryNames方法加载资源类
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
}
SpringFactoriesLoader
/**
*SpringFactoriesLoader是一种加载机制,方便框架内部使用的一些需要被加载的目标工厂。加载的资源位于多个类路径下的jar包下的META-INF/spring.factories路径下的资源文件。文件必须是属性配置格式。key是接口或抽象类全路径名称,value是多个实现类,用,隔开。
*
*/
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap<>();
private SpringFactoriesLoader() {
}
//根据加载类类型和类加载器进行类加载
public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
Assert.notNull(factoryType, "'factoryType' must not be null");
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
//从资源文件中获取对应类型的类的全路径名称
List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
}
List<T> result = new ArrayList<>(factoryImplementationNames.size());
for (String factoryImplementationName : factoryImplementationNames) {、
//通过反射实例化类对象
result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
}
//对类对象进行排序
AnnotationAwareOrderComparator.sort(result);
return result;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
Map<String, List<String>> result = cache.get(classLoader);
if (result != null) {
return result;
}
result = new HashMap<>();
try {
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryTypeName = ((String) entry.getKey()).trim();
String[] factoryImplementationNames =
StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
for (String factoryImplementationName : factoryImplementationNames) {
result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
.add(factoryImplementationName.trim());
}
}
}
// Replace all lists with unmodifiable lists containing unique elements
result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
cache.put(classLoader, result);
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
return result;
}
@SuppressWarnings("unchecked")
private static <T> T instantiateFactory(String factoryImplementationName, Class<T> factoryType, ClassLoader classLoader) {
try {
Class<?> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
throw new IllegalArgumentException(
"Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
}
return (T) ReflectionUtils.accessibleConstructor(factoryImplementationClass).newInstance();
}
catch (Throwable ex) {
throw new IllegalArgumentException(
"Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]",
ex);
}
}
}
run(String...args)实例函数
开启计时任务,随后创建一个引导上下文DefaultBootstrapContext 、调用configureHeadlessProperty配置无头属性,获取SpringApplicationRunListener类型的监听器,并根据引导上下文和主类发布启动事件,根据命令行参数构建应用参数,根据运行监听器、引导上下文、应用参数 准备应用环境;
createApplicationContext()方法创建应用上下文;
context.setApplicationStartup(this.applicationStartup)调用[父类的setApplicationStartup],设置应用启动,此处内部方法内部分别调用的是GenericApplicationContext和[AbstractBeanFactory]#(AbstractBeanFactory)的setApplicationStartup方法;
调用prepareContext方法,使用引导上下文、应用上下文、环境、监听器等准备上下文,接下来看一下prepareContext方法都做了哪些工作。
public class SpringApplication {
private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
//启动Spring应用,创建和刷新一个新的应用上下文,args:命令行参数
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//创建一个引导上下文
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
//获取SpringApplicationRunListener类型的监听器,并根据引导上下文和主类发布启动事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
//根据命令行参数构建应用参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//根据运行监听器、引导上下文、应用参数 准备应用环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
//配置可忽略的BeanInfo信息
configureIgnoreBeanInfo(environment);
//打印banner,当没有配置自定义banner文件时,默认在控制台输出默认logo
Banner printedBanner = printBanner(environment);
//创建应用上下文 AnnotationConfigServletWebServerApplicationContext
context = createApplicationContext();
//此处内部方法内部分别调用的是GenericApplicationContext和AbstractBeanFactory的setApplicationStartup方法
context.setApplicationStartup(this.applicationStartup);
//使用引导上下文、应用上下文、环境、监听器等准备上下文
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
//然后调用刷新应用上下文方法
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
private void configureHeadlessProperty() {
System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}
}
DefaultBootstrapContext
public class SpringApplication {
private DefaultBootstrapContext createBootstrapContext() {
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
//此时的bootstrapRegistryInitializers为空,没有任何处理
this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));
return bootstrapContext;
}
}
/**
*一个简单的引导上下文,在启动和环境后处理期间可用,直到准备好ApplicationContext。
*
*/
public class DefaultBootstrapContext implements ConfigurableBootstrapContext {
}
ConfigurableEnvironment
sources.propertySourceList
0 = {PropertySource$StubPropertySource@2347} "StubPropertySource {name='servletConfigInitParams'}"
1 = {PropertySource$StubPropertySource@2348} "StubPropertySource {name='servletContextInitParams'}"
2 = {PropertiesPropertySource@2349} "PropertiesPropertySource {name='systemProperties'}"
3 = {SystemEnvironmentPropertySource@2350} "SystemEnvironmentPropertySource {name='systemEnvironment'}"
getOrCreateEnvironment()获取ApplicationServletEnvironment,主要从类路径下面加载配置文件资源,包括加载激活文件等;
configureEnvironment配置属性源和添加命令行参数;
ConfigurationPropertySources.attach:添加附件配置属性
listeners.environmentPrepared:发布环境已经准备好事件通知
DefaultPropertiesPropertySource.moveToEnd:将默认配置文件属性移至最后
bindToSpringApplication:将环境信息绑定至Spring应用
public class SpringApplication {
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
listeners.environmentPrepared(bootstrapContext, environment);
DefaultPropertiesPropertySource.moveToEnd(environment);
Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
"Environment prefix cannot be set via properties.");
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
}
//根据应用的不同类型创建不同的环境,此处返回ApplicationServletEnvironment
switch (this.webApplicationType) {
case SERVLET:
return new ApplicationServletEnvironment();
case REACTIVE:
return new ApplicationReactiveWebEnvironment();
default:
return new ApplicationEnvironment();
}
}
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
//添加转化服务
environment.setConversionService(new ApplicationConversionService());
}
//配置属性源
configurePropertySources(environment, args);
//默认空属性
configureProfiles(environment, args);
}
//添加、移除或重排序属性源
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
if (!CollectionUtils.isEmpty(this.defaultProperties)) {
DefaultPropertiesPropertySource.addOrMerge(this.defaultProperties, sources);
}
//添加命令行参数
if (this.addCommandLineProperties && args.length > 0) {
String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
if (sources.contains(name)) {
PropertySource<?> source = sources.get(name);
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(
new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
composite.addPropertySource(source);
sources.replace(name, composite);
}
else {
sources.addFirst(new SimpleCommandLinePropertySource(args));
}
}
}
}
ApplicationServletEnvironment
ApplicationServletEnvironment 主要从类路径下面加载配置文件资源,包括加载激活文件等
class ApplicationServletEnvironment extends StandardServletEnvironment {
@Override
protected String doGetActiveProfilesProperty() {
return null;
}
@Override
protected String doGetDefaultProfilesProperty() {
return null;
}
@Override
protected ConfigurablePropertyResolver createPropertyResolver(MutablePropertySources propertySources) {
return ConfigurationPropertySources.createPropertyResolver(propertySources);
}
}
ConfigurableApplicationContext
使用applicationContextFactory上下文工厂创建一个应用上下文,其中applicationContextFactory是一个成员变量
public class SpringApplication {
private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;
protected ConfigurableApplicationContext createApplicationContext() {
//进入default的lambda表达式,返回AnnotationConfigServletWebServerApplicationContext
return this.applicationContextFactory.create(this.webApplicationType);
}
}
ApplicationContextFactory
根据webApplicationType返回应用上下文,此处返回AnnotationConfigServletWebServerApplicationContext
public interface ApplicationContextFactory {
ApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch (webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
}
catch (Exception ex) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
+ "you may need a custom ApplicationContextFactory", ex);
}
};
ConfigurableApplicationContext create(WebApplicationType webApplicationType);
}
AnnotationConfigServletWebServerApplicationContext
setEnvironment方法设置资源读取,super.setEnvironment方法调用了AbstractApplicationContext的setEnvironment方法,然后为成员变量赋值
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
private final ClassPathBeanDefinitionScanner scanner;
//调用了scanner的clearCache清除缓存方法,此时的scanner = ClassPathBeanDefinitionScanner 类路径BeanDefinition
//扫描器,随后调用父类的prepareRefresh,即AbstractApplicationContext的prepareRefresh
@Override
protected void prepareRefresh() {
this.scanner.clearCache();
super.prepareRefresh();
}
}
F:资源读取功能
ServletWebServerApplicationContext
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
}
GenericWebApplicationContext
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
}
GenericApplicationContext
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
@Nullable
private ConfigurableEnvironment environment;
@Override
public void setApplicationStartup(ApplicationStartup applicationStartup) {
super.setApplicationStartup(applicationStartup);
this.beanFactory.setApplicationStartup(applicationStartup);
}
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
this.environment = environment;
}
}
AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//应用启动的体系
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;
//在refresh刷新的时候,应用工厂后处理器
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
@Override
public void setApplicationStartup(ApplicationStartup applicationStartup) {
Assert.notNull(applicationStartup, "applicationStartup should not be null");
this.applicationStartup = applicationStartup;
}
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}
}
DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
}
AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
}
AbstractBeanFactory
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
//应用启动的体系
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;
public void setApplicationStartup(ApplicationStartup applicationStartup) {
Assert.notNull(applicationStartup, "applicationStartup should not be null");
this.applicationStartup = applicationStartup;
}
}
prepareContext
context.setEnvironment(environment)将资源环境设置给应用上下文,此时context = AnnotationConfigServletWebServerApplicationContext,即调用[AnnotationConfigServletWebServerApplicationContext]#(AnnotationConfigServletWebServerApplicationContext)的setEnvironment方法;后置处理应用上下文,主要为beanfactory设置了数据转换服务;为上下文应用初始化bean,主要是从Spring类路径下加载的Bean;使用SpringApplicationRunListeners 发布contextPrepared事件;关闭引导上下文,并发布相应事件;注册应用参数单例对象; 加载资源,返回所有源的不可变集合,包括首要类和配置资源的集合;根据资源路径向上下文加载BeanDefinition,此处加载的是首类UserProviderBootstrap的BeanDefinition;监听器发布上下文已加载事件,至此,一级的BeanDefinition以加载注册完毕。
public class SpringApplication {
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
//将资源环境设置给应用上下文
context.setEnvironment(environment);
//后置处理应用上下文,主要为beanfactory设置了数据转换服务
postProcessApplicationContext(context);
//为上下文应用初始化bean
applyInitializers(context);
//发布contextPrepared事件
listeners.contextPrepared(context);
//关闭引导上下文,并发布相应事件
bootstrapContext.close(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans 添加特定于引导的单例bean
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//注册应用参数单例对象
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
//设置允许Bean定义覆写为false
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//lazyInitialization = false,不添加懒加载bean工厂后置处理器
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources 加载资源,返回所有源的不可变集合,包括首要类和配置资源的集合
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
//根据资源路径向上下文加载BeanDefinition,此处加载的是首类UserProviderBootstrap的BeanDefinition
load(context, sources.toArray(new Object[0]));
//监听器发布上下文已加载事件
listeners.contextLoaded(context);
}
}
postProcessApplicationContext
应用任何相关的后处理ApplicationContext。子类可以根据需要应用额外的处理.在第一次执行的时候,beanNameGenerator 、resourceLoader 都为空。调用setConversionService方法,为工厂添加转换服务。context.getEnvironment() = AbstractEnvironment;context.getBeanFactory().setConversionService为AbstractBeanFactory设置ConversionService;
public class SpringApplication {
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
if (this.beanNameGenerator != null) {
context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
this.beanNameGenerator);
}
if (this.resourceLoader != null) {
if (context instanceof GenericApplicationContext) {
((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
}
if (context instanceof DefaultResourceLoader) {
((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader());
}
}
if (this.addConversionService) {
context.getBeanFactory().setConversionService(context.getEnvironment().getConversionService());
}
}
AbstractEnvironment
this.propertyResolver.getConversionService()返回的服务为:ApplicationConversionService
public abstract class AbstractEnvironment implements ConfigurableEnvironment {
public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";
public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";
public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";
protected static final String RESERVED_DEFAULT_PROFILE_NAME = "default";
private final ConfigurablePropertyResolver propertyResolver;
@Override
public ConfigurableConversionService getConversionService() {
return this.propertyResolver.getConversionService();
}
}
ApplicationConversionService
public class ApplicationConversionService extends FormattingConversionService {
//添加SpringBoot应用常用的转换服务
public static void addApplicationConverters(ConverterRegistry registry) {
addDelimitedStringConverters(registry);
registry.addConverter(new StringToDurationConverter());
registry.addConverter(new DurationToStringConverter());
registry.addConverter(new NumberToDurationConverter());
registry.addConverter(new DurationToNumberConverter());
registry.addConverter(new StringToPeriodConverter());
registry.addConverter(new PeriodToStringConverter());
registry.addConverter(new NumberToPeriodConverter());
registry.addConverter(new StringToDataSizeConverter());
registry.addConverter(new NumberToDataSizeConverter());
registry.addConverter(new StringToFileConverter());
registry.addConverter(new InputStreamSourceToByteArrayConverter());
registry.addConverterFactory(new LenientStringToEnumConverterFactory());
registry.addConverterFactory(new LenientBooleanToEnumConverterFactory());
if (registry instanceof ConversionService) {
addApplicationConverters(registry, (ConversionService) registry);
}
}
}
applyInitializers
getInitializers()获取到初始化BeanName,包括:
0 = {DelegatingApplicationContextInitializer@3860}
1 = {SharedMetadataReaderFactoryContextInitializer@3867}
2 = {ContextIdApplicationContextInitializer@3868}
3 = {ConfigurationWarningsApplicationContextInitializer@3869}
4 = {RSocketPortInfoApplicationContextInitializer@3870}
5 = {ServerPortInfoApplicationContextInitializer@3871}
6 = {ConditionEvaluationReportLoggingListener@3872}
,然后调用初始化Bean的initialize方法,所有的这些初始化类都没有进行启动服务的实质性操作,都是通过注册对象,埋点,后面invokeBeanFactoryPostProcessors才真正调用初始化方法,而且是在项目启动之前
public class SpringApplication {
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
public Set<ApplicationContextInitializer<?>> getInitializers() {
return asUnmodifiableOrderedSet(this.initializers);
}
DelegatingApplicationContextInitializer委托应用程序上下文初始化器
空实现
public class DelegatingApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
public void initialize(ConfigurableApplicationContext context) {
ConfigurableEnvironment environment = context.getEnvironment();
List<Class<?>> initializerClasses = getInitializerClasses(environment);
if (!initializerClasses.isEmpty()) {
applyInitializerClasses(context, initializerClasses);
}
}
}
SharedMetadataReaderFactoryContextInitializer共享元数据读取器工厂上下文初始化器
初始化动作构建了一个CachingMetadataReaderFactoryPostProcessor缓存元数据读取工厂后置处理器
applicationContext.addBeanFactoryPostProcessor往应用上下文AbstractApplicationContext添加Bean工厂后置处理器。
class SharedMetadataReaderFactoryContextInitializer
public void initialize(ConfigurableApplicationContext applicationContext) {
BeanFactoryPostProcessor postProcessor = new CachingMetadataReaderFactoryPostProcessor(applicationContext);
applicationContext.addBeanFactoryPostProcessor(postProcessor);
}
/*
*扩展到标准BeanFactoryPostProcessor SPI,允许在常规BeanFactoryPostProcessor检测开始之前注册
*更多的bean定义。特别是,BeanDefinitionRegistryPostProcessor可以注册进一步的bean定义,这些bean
*定义依次定义BeanFactoryPostProcessor实例。
*/
static class CachingMetadataReaderFactoryPostProcessor
implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
}
}
ContextIdApplicationContextInitializer初始化上下文ID对象
public class ContextIdApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
public void initialize(ConfigurableApplicationContext applicationContext) {
ContextId contextId = getContextId(applicationContext);
applicationContext.setId(contextId.getId());
applicationContext.getBeanFactory().registerSingleton(ContextId.class.getName(), contextId);
}
}
ConfigurationWarningsApplicationContextInitializer配置警告初始化对象
生成了一个配置警告后置处理器,主要是对ComponentScan对象进行检查
public class ConfigurationWarningsApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext context) {
context.addBeanFactoryPostProcessor(new ConfigurationWarningsPostProcessor(getChecks()));
}
}
RSocketPortInfoApplicationContextInitializer网络端口信息初始化对象
public class RSocketPortInfoApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
//注入一个端口检查和设置的监听器,对应的事件RSocketServerInitializedEvent
applicationContext.addApplicationListener(new Listener(applicationContext));
}
private static class Listener implements ApplicationListener<RSocketServerInitializedEvent> {
}
}
ServerPortInfoApplicationContextInitializer服务器端口信息初始化对象
本是是一个应用事件
public class ServerPortInfoApplicationContextInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext>, ApplicationListener<WebServerInitializedEvent> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.addApplicationListener(this);
}
}
ConditionEvaluationReportLoggingListener条件评估报告日志监听器
本是也是一个初始化对象
public class ConditionEvaluationReportLoggingListener
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
applicationContext.addApplicationListener(new ConditionEvaluationReportListener());
if (applicationContext instanceof GenericApplicationContext) {
// Get the report early in case the context fails to load
this.report = ConditionEvaluationReport.get(this.applicationContext.getBeanFactory());
}
}
}
applyInitializers方法中添加了两个BeanFactoryPostProcessor:org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer.ConfigurationWarningsPostProcessor、
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor
getAllSources()
public class SpringApplication {
//返回所有源的不可变集合,包括首要类和配置资源的集合
public Set<Object> getAllSources() {
Set<Object> allSources = new LinkedHashSet<>();
if (!CollectionUtils.isEmpty(this.primarySources)) {
allSources.addAll(this.primarySources);
}
if (!CollectionUtils.isEmpty(this.sources)) {
allSources.addAll(this.sources);
}
return Collections.unmodifiableSet(allSources);
}
}
load(context, sources.toArray(new Object[0]))
根据getBeanDefinitionRegistry(context)返回的注册器,创建一个bean加载器,通过new BeanDefinitionLoader,此时对象成员中,beanNameGenerator、resourceLoader 、environment 都为空,调用loader.load,即BeanDefinitionLoader.load
public class SpringApplication {
//向上下文加载bean
protected void load(ApplicationContext context, Object[] sources) {
if (logger.isDebugEnabled()) {
logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
}
//创建BeanDefinitionLoader加载器
BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
if (this.beanNameGenerator != null) {
loader.setBeanNameGenerator(this.beanNameGenerator);
}
if (this.resourceLoader != null) {
loader.setResourceLoader(this.resourceLoader);
}
if (this.environment != null) {
loader.setEnvironment(this.environment);
}
loader.load();
}
protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
return new BeanDefinitionLoader(registry, sources);
}
}
getBeanDefinitionRegistry(context)获取注册器
根据上下文的不同类型,返回不同的注册器,此处返回上下文本身,因为上下文本身实现了BeanDefinitionRegistry接口
public class SpringApplication {
private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) {
if (context instanceof BeanDefinitionRegistry) {
return (BeanDefinitionRegistry) context;
}
if (context instanceof AbstractApplicationContext) {
return (BeanDefinitionRegistry) ((AbstractApplicationContext) context).getBeanFactory();
}
throw new IllegalStateException("Could not locate BeanDefinitionRegistry");
}
}
BeanDefinitionLoader
BeanDefinitionLoader是一个门面类:在类构造函数中,构造了AnnotatedBeanDefinitionReader、XmlBeanDefinitionReader和ClassPathBeanDefinitionScanner三个类型的读取类。并在ClassPathBeanDefinitionScanner中添加了一个类排除过滤器。
/**
*从给定的资源文件加载Bean Definition,包括XML和java config.是AnnotatedBeanDefinitionReader, XmlBeanDefinitionReader
*and ClassPathBeanDefinitionScanner的门面类。
*/
class BeanDefinitionLoader {
BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {
Assert.notNull(registry, "Registry must not be null");
Assert.notEmpty(sources, "Sources must not be empty");
this.sources = sources;
this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
this.xmlReader = (XML_ENABLED ? new XmlBeanDefinitionReader(registry) : null);
this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null);
this.scanner = new ClassPathBeanDefinitionScanner(registry);
this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
}
//加载所有的资源到读取器中
void load() {
for (Object source : this.sources) {
load(source);
}
}
//此处使用重载的方式,加载不同类型的资源文件,此处的资源类型为Class
private void load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class<?>) {
load((Class<?>) source);
return;
}
if (source instanceof Resource) {
load((Resource) source);
return;
}
if (source instanceof Package) {
load((Package) source);
return;
}
if (source instanceof CharSequence) {
load((CharSequence) source);
return;
}
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}
private void load(Class<?> source) {
if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
// Any GroovyLoaders added in beans{} DSL can contribute beans here
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());
}
//判断类是否符合条件
if (isEligible(source)) {
//使用注解读取器注册资源
this.annotatedReader.register(source);
}
}
//不是匿名类、Groovy闭包和有构造函数
private boolean isEligible(Class<?> type) {
return !(type.isAnonymousClass() || isGroovyClosure(type) || hasNoConstructors(type));
}
}
ExcludeFilter的作用?
AnnotatedBeanDefinitionReader annotatedReader
此处使用注解BeanDefinition读取器读取配置类上的BeanDefinition,具体过程可参考使用AnnotatedBeanDefinitionReader注解BeanDefinition的注册
public class AnnotatedBeanDefinitionReader {
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
//从给定的Bean中注册bean,推导元数据信息从声明的类注解上
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
/*
*beanClass:bean class; name:bean执行的显式名称
*qualifiers:注解限定符 supplier:创建bean实例之后的回调功能
*customizers:一个或多个回调函数用于定制工厂的BeanDefinition,例如设置lazy-init或primary标志
*/
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//首先根据传入的首要类构建一个AnnotatedGenericBeanDefinition:一般注解型BeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
AbstractBeanDefinitionReader xmlReader
ClassPathBeanDefinitionScanner scanner
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
}
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
public void clearCache() {
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
}
refreshContext
refresh内部调用applicationContext的refresh方法,此时applicationContext = ServletWebServerApplicationContext
public class SpringApplication {
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
//注册一个关闭回调钩子,在上下文关闭的时候,进行调用
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
}
ServletWebServerApplicationContext
方法内部调用父类的refresh方法,此时父类 = AbstractApplicaitonContext
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;
}
}
}
AbstractApplicaitonContext.refresh() 刷新上下文
刷新方法中,主要有以下几个过程:
1、为了刷新准备上下文,此处的prepareRefresh调用了子类AnnotationConfigServletWebServerApplicationContext的prepareRefresh方法;
调用了AnnotationConfigServletWebServerApplicationContext prepareRefresh方法,方法内部调用了scanner的的clearCache清除缓存方法,此时的scanner = ClassPathBeanDefinitionScanner 类路径BeanDefinition扫描器,随后调用父类的prepareRefresh,即AbstractApplicationContext的prepareRefresh;继续执行自身类中的方法
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
//主要完成了servlet参数的设置、所需属性的解析验证
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//准备在此上下文中使用的bean工厂。 主要是注册了一些默认的单例对象
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//允许在上下文子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
//创建了一个开始步骤的bean后置处理器
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
//调用在上下文中注册为bean的工厂处理器。此时BeanFactory中包含的工厂处理器有:
//ConfigurationWarningsApplicationContextInitializer.ConfigurationWarningsPostProcessor
//SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
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();
contextRefresh.end();
}
}
}
}
prepareRefresh
主要完成了servlet参数的设置、所需属性的解析验证
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void prepareRefresh() {
// Switch to active.激活上下文刷新
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
//初始化上下文环境中的占位符属性资源,调用子类中的实现方法,主要实现了对ServletContextPropertySource和
//ServletConfigPropertySource的替换
initPropertySources();
// Validate that all properties marked as required are resolvable:验证所有标记为必需的属性都是可解析的
// see ConfigurablePropertyResolver#setRequiredProperties
//getEnvironment = ApplicationServletEnvironment,调用的是父类AbstractEnvironment 的validateRequiredProperties方法
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
//构建早期应用监听者
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
}
initPropertySources()
env =
ApplicationServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, StubPropertySource {name='servletConfigInitParams'}, StubPropertySource {name='servletContextInitParams'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='Config resource 'class path resource [application.properties]' via location 'optional:classpath:/''}]}
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
//替换Servlet上下文中的属性资源
@Override
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
//env = ApplicationServletEnvironment instanceof ConfigurableWebEnvironment
if (env instanceof ConfigurableWebEnvironment) {
//方法内部调用了StandardServletEnvironment的initPropertySources方法
((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
}
}
}
StandardServletEnvironment
方法内部调用了WebApplicationContextUtils网络应用上下文工具类的initServletPropertySources初始化Servlet属性资源
getPropertySources()=
0 = {ConfigurationPropertySourcesPropertySource@4425} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}"
1 = {PropertySource$StubPropertySource@4426} "StubPropertySource {name='servletConfigInitParams'}"
2 = {PropertySource$StubPropertySource@4427} "StubPropertySource {name='servletContextInitParams'}"
3 = {PropertiesPropertySource@4428} "PropertiesPropertySource {name='systemProperties'}"
4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@4429} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
5 = {RandomValuePropertySource@4430} "RandomValuePropertySource {name='random'}"
6 = {OriginTrackedMapPropertySource@4431} "OriginTrackedMapPropertySource {name='Config resource 'class path resource [application.properties]' via location 'optional:classpath:/''}"
其中OriginTrackedMapPropertySource存储了配置文件的key-value键值对,
调用WebApplicationContextUtils.initServletPropertySources初始化Servlet属性源
public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {
@Override
public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
}
}
WebApplicationContextUtils
public abstract class WebApplicationContextUtils {
//初始化属性源,本质上是利用传入的参数代理已有的配置
public static void initServletPropertySources(MutablePropertySources sources,
@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
Assert.notNull(sources, "'propertySources' must not be null");
String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
if (servletContext != null && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletContextPropertySource(name, servletContext));
}
name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
if (servletConfig != null && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
}
}
}
validateRequiredProperties
方法内部调用的是解析器的validateRequiredProperties方法
public abstract class AbstractEnvironment implements ConfigurableEnvironment {
private final ConfigurablePropertyResolver propertyResolver;
@Override
public void validateRequiredProperties() throws MissingRequiredPropertiesException {
this.propertyResolver.validateRequiredProperties();
}
}
AbstractPropertyResolver 占位符解析器
public abstract class AbstractPropertyResolver implements ConfigurablePropertyResolver {
private String placeholderPrefix = SystemPropertyUtils.PLACEHOLDER_PREFIX;//"${"
private String placeholderSuffix = SystemPropertyUtils.PLACEHOLDER_SUFFIX;//"}"
private String valueSeparator = SystemPropertyUtils.VALUE_SEPARATOR;":"
public void validateRequiredProperties() {
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {
if (this.getProperty(key) == null) {
ex.addMissingRequiredProperty(key);
}
}
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
}
obtainFreshBeanFactory
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//调用子类GenericApplicationContext的refreshBeanFactory方法,更改刷新状态,设置序列化ID
refreshBeanFactory();
//调用子类GenericApplicationContext的getBeanFactory方法,返回BeanFactory
return getBeanFactory();
}
}
GenericApplicationContext
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final AtomicBoolean refreshed = new AtomicBoolean();//原子类
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
private final DefaultListableBeanFactory beanFactory;
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
}
prepareBeanFactory(beanFactory)
设置类加载器;添加Spring表达式解析器;根据resourceLoader和属性解析器构建资源编辑注册器进行添加;
配置beanFactory的上下文回调ApplicationContextAwareProcessor,即BeanPostProcessor,同时设置自动织入时忽略的依赖接口,这种方式保证了某些依赖由框架设置,而非自动装配或者由用户自己设置依赖,具体实现和功能可参考博客打开BeanFactory ignoreDependencyInterface方法的正确姿势;
//配置工厂的标准上下文特征,比如上下文的ClassLoader和后处理程序。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//由Spring . spell .ignore系统属性控制的布尔标志,该属性指示Spring忽略SpEL
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
//工厂中LoadTimeWeaver bean的名称。 如果提供了这样一个bean,那么上下文将使用一个临时ClassLoader进行类型匹配,
//以便允许LoadTimeWeaver处理所有实际的bean类
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
//
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
//在普通工厂中没有将BeanFactory接口注册为可解析类型。
// MessageSource registered (and found for autowiring) as a bean.
//MessageSource注册为bean(并用于自动装配)。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
//注册了一个应用程序监听器探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
//探测一个加载期织入器,如果发现了,准备织入
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
//添加一个加载期织入包装后置处理器,同时设置临时类加载器
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
//向工厂注册默认的environment对象,environment从应用上下文中获取
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
//向工厂注册默认的systemProperties bean
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
//向工厂注册默认的systemEnvironment bean
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
//向工厂注册默认的applicationStartup bean
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
}
prepareBeanFactory方法中注册的单例对象有:environment 、systemProperties 、systemEnvironment 、applicationStartup
prepareBeanFactoryf方法中注册的BeanPostProcessor有:ApplicationContextAwareProcessor、ApplicationListenerDetector、
StandardBeanExpressionResolver
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()))给BeanFactory设置了一个Spel表达式解析器,详细过程可参考玩转Spring中强大的spel表达式
registerResolvableDependency 注册要解析的依赖
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
Assert.notNull(dependencyType, "Dependency type must not be null");
if (autowiredValue != null) {
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
throw new IllegalArgumentException("Value [" + autowiredValue +
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
}
this.resolvableDependencies.put(dependencyType, autowiredValue);
}
}
}
postProcessBeanFactory(beanFactory)
调用了子类AnnotationConfigServletWebServerApplicationContext的postProcessBeanFactory方法,方法内部继续调用父类的postProcessBeanFactory方法,postProcessBeanFactory方法内部添加了ServletContextAwareProcessor类型的后置处理器,添加了web应用作用域范围;
随后,判断扫描包是否不为空,如果不为空,调用scanner ClassPathBeanDefinitionScanner进行BeanDefinition注册;
判断annotatedClasses 注解类是否不为空,如果不为空,调用reader AnnotatedBeanDefinitionReader 进行BeanDefinition注册
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
implements AnnotationConfigRegistry {
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
}
- ServletWebServerApplicationContext
添加了WebApplicationContextServletContextAwareProcessor 后置处理器,同时添加了忽略依赖的接口:ServletContextAware;
构建应用作用域范围[ExistingWebApplicationScopes]内部类;
调用工具类WebApplicationContextUtils注册web应用作用域
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes();
}
private void registerWebApplicationScopes() {
//创建ExistingWebApplicationScopes 实例对象;
ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(getBeanFactory());
//注册web应用作用域
WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
existingScopes.restore();
}
public static class ExistingWebApplicationScopes {
public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
//scopes = session、request
for (String scopeName : SCOPES) {
//从beanFactory中获取作用域值,默认返回为空
Scope scope = beanFactory.getRegisteredScope(scopeName);
if (scope != null) {
this.scopes.put(scopeName, scope);
}
}
}
}
}
postProcessBeanFactory添加的BeanPostProcessor后置处理器:WebApplicationContextServletContextAwareProcessor
- WebApplicationContextServletContextAwareProcessor
包含了WebApplicationContext上下文,同时提供了获取ServletContext、ServletConfig的方法
public class WebApplicationContextServletContextAwareProcessor extends ServletContextAwareProcessor {
public WebApplicationContextServletContextAwareProcessor(ConfigurableWebApplicationContext webApplicationContext) {
Assert.notNull(webApplicationContext, "WebApplicationContext must not be null");
this.webApplicationContext = webApplicationContext;
}
@Override
protected ServletContext getServletContext() {
ServletContext servletContext = this.webApplicationContext.getServletContext();
return (servletContext != null) ? servletContext : super.getServletContext();
}
@Override
protected ServletConfig getServletConfig() {
ServletConfig servletConfig = this.webApplicationContext.getServletConfig();
return (servletConfig != null) ? servletConfig : super.getServletConfig();
}
}
WebApplicationContextUtils
public abstract class WebApplicationContextUtils {
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
registerWebApplicationScopes(beanFactory, null);
}
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
//默认scope为空
if (sc != null) {
//如果sc不为空,构建一个ServletContextScope ,并注册为application范围作用域
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// Register as ServletContext attribute, for ContextCleanupListener to detect it.
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
}
registerWebApplicationScopes方法中注册了四个要自动织入的解析依赖对象:ServletRequest、ServletResponse、HttpSession、WebRequest
invokeBeanFactoryPostProcessors(beanFactory)
实例化并调用所有已注册的BeanFactoryPostProcessor bean,如果给出显式顺序,则遵循此顺序。具体调用过程查看文章SpringBoot启动过程中,BeanFactoryPostProcessors的处理过程,包括启动类的加载和自动装配类的加载
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
}
PostProcessorRegistrationDelegate
//委托AbstractApplicationContext的后处理器处理
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
//不要在这里初始化FactoryBeans:我们需要让所有常规bean保持未初始化状态,以便bean工厂后处理程序应用于它们!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//调用propertySourcesPlaceholderConfigurer后置处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//此处的后置处理器包括3个
//0 = {EventListenerMethodProcessor@15134}
//1 = {ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor@15135}
//2 = {AopAutoConfiguration$ClassProxyingConfiguration$lambda@15136}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
.tag("postProcessor", postProcessor::toString);
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();
}
}
}
registerBeanPostProcessors(beanFactory)
通过注册Bean后置处理器,拦截Bean的创建
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
/**
*实例化和注册所有的BeanPostProcessor bean,如果给出,请遵守显式的顺序。
*必须在应用程序bean的任何实例化之前调用。
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
}
PostProcessorRegistrationDelegate.registerBeanPostProcessors 注册BeanPostProcessor,在创建Bean的时候使用
从BeanDefinition获取BeanPostProcessor类型的名称:
0 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
1 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
2 = "org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor"
3 = "webServerFactoryCustomizerBeanPostProcessor"
4 = "errorPageRegistrarBeanPostProcessor"
5 = "referenceAnnotationBeanPostProcessor"
6 = "org.springframework.aop.config.internalAutoProxyCreator"
注册完Bean后置处理器,beanPostProcess执行告一段落,返回beanPostProcess.end();
final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//从BeanDefinition获取BeanPostProcessor类型的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//按优先级对BeanPostProcessor后置处理器进行分组,在获得对应BeanPostProcessor类型的时候,并进行实例化。
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//此处依次添加的后置处理器有AutowiredAnnotationBeanPostProcessor、
//CommonAnnotationBeanPostProcessor、ConfigurationPropertiesBindingPostProcessor、
//ReferenceAnnotationBeanPostProcessor
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//如果属于MergedBeanDefinitionPostProcessor类型,则添加到内置后置处理器变量中
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//org.springframework.aop.config.internalAutoProxyCreator
orderedPostProcessorNames.add(ppName);
}
else {
//webServerFactoryCustomizerBeanPostProcessor、errorPageRegistrarBeanPostProcessor
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 首先,注册实现prioritorderordered的BeanPostProcessors。
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 随后,注册实现了Ordered接口的BeanPostProcessors InfrastructureAdvisorAutoProxyCreator
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//同上
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
//添加了一个Bean事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
/**
* 将对应的postProcessor注册到BeanFactory的成员变量BeanPostProcessors中
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
if (beanFactory instanceof AbstractBeanFactory) {
// Bulk addition is more efficient against our CopyOnWriteArrayList there
((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
}
else {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}
}
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
ConfigurationPropertiesBindingPostProcessor
ReferenceAnnotationBeanPostProcessor
InfrastructureAdvisorAutoProxyCreator
initMessageSource() 用于国际化
为BeanFactory添加了一个messageSource单例对象
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
}
initApplicationEventMulticaster() 为这个上下文初始化事件多播器。
此处进入else逻辑,为上下文创建了一个SimpleApplicationEventMulticaster简单应用事件多播器,并注册为单例对象
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
}
onRefresh() 在特定的上下文子类中初始化其他特殊bean 主题对象和创建webServer
首先从AbstractApplicaitonContext类中调用子类ServletWebServerApplicationContext的onRefresh方法,方法内部首先调用了父类GenericWebApplicationContext的onRefresh方法,父类方法创建了主题功能,然后调用createWebServer方法。
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
@Override
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
}
GenericWebApplicationContext.onRefresh()
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
/**
* Initialize the theme capability. 初始化主题功能。
*/
@Override
protected void onRefresh() {
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
}
UiApplicationContextUtils 初始化主题功能
此处进入else逻辑部分,context.getParent()获取为空,进入else,创建了ResourceBundleThemeSource返回
public abstract class UiApplicationContextUtils {
public static ThemeSource initThemeSource(ApplicationContext context) {
if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
// Make ThemeSource aware of parent ThemeSource.
if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
if (hts.getParentThemeSource() == null) {
// Only set parent context as parent ThemeSource if no parent ThemeSource
// registered already.
hts.setParentThemeSource((ThemeSource) context.getParent());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using ThemeSource [" + themeSource + "]");
}
return themeSource;
}
else {
// Use default ThemeSource to be able to accept getTheme calls, either
// delegating to parent context's default or to local ResourceBundleThemeSource.
HierarchicalThemeSource themeSource = null;
if (context.getParent() instanceof ThemeSource) {
themeSource = new DelegatingThemeSource();
themeSource.setParentThemeSource((ThemeSource) context.getParent());
}
else {
themeSource = new ResourceBundleThemeSource();
}
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
"': using default [" + themeSource + "]");
}
return themeSource;
}
}
}
ServletWebServerApplicationContext.createWebServer
此方法创建web服务器,进入if逻辑,调用getWebServerFactory获取服务器工厂,返回工厂名字tomcatServletWebServerFactory,根据BeanDefinition name返回Bean实例对象。
通过加载Bean,此处调用了DispatchServlet的onstartup方法和其他Bean的onstartup方法。对tomcat的生命周期进行了加载。
调用initPropertySources方法,对数据源中关于servlet的参数进行替换
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
//从BeanFactory获取factory 实例对象
ServletWebServerFactory factory = getWebServerFactory();
createWebServer.tag("factory", factory.getClass().toString());
this.webServer = factory.getWebServer(getSelfInitializer());
createWebServer.end();
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
protected ServletWebServerFactory getWebServerFactory() {
// Use bean names so that we don't consider the hierarchy
// beanNames = [tomcatServletWebServerFactory]
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
if (beanNames.length == 0) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
+ "ServletWebServerFactory bean.");
}
if (beanNames.length > 1) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
}
//返回Bean实例对象
return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
}
//自我初始化函数
private void selfInitialize(ServletContext servletContext) throws ServletException {
//此处的servletContext是在创建tomcat服务器的时候,创建的,在回调时传入该变量
prepareWebApplicationContext(servletContext);
//注册一个应用范围域的作用域,在工厂和servletContext中注册该作用域
registerApplicationScope(servletContext);
//将servletContext注册为bean对象
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
//获取servlet上下文初始化Bean,并调用对应Bean的startup方法,触发servletContext启动事件
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}
//准备Web应用上下文
protected void prepareWebApplicationContext(ServletContext servletContext) {
Object rootContext = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (rootContext != null) {
if (rootContext == this) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - "
+ "check whether you have multiple ServletContextInitializers!");
}
return;
}
//进入try逻辑,将当前web应用上下文绑定至servletContext servlet上下文
servletContext.log("Initializing Spring embedded WebApplicationContext");
try {
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this);
if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name ["
+ WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
//调用setServletContext方法,将servlet上下文绑定至web应用上下文
setServletContext(servletContext);
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - getStartupDate();
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}
}
catch (RuntimeException | Error ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
}
//注册一个应用范围域的作用域,在工厂和servletContext中注册该作用域
private void registerApplicationScope(ServletContext servletContext) {
ServletContextScope appScope = new ServletContextScope(servletContext);
getBeanFactory().registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// Register as ServletContext attribute, for ContextCleanupListener to detect it.
servletContext.setAttribute(ServletContextScope.class.getName(), appScope);
}
//构建了一个ServletContextInitializerBeans实例对象
protected Collection<ServletContextInitializer> getServletContextInitializerBeans() {
return new ServletContextInitializerBeans(getBeanFactory());
}
}
TomcatServletWebServerFactory.getWebServer
public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory
implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
}
WebApplicationContext
public interface WebApplicationContext extends ApplicationContext {
// Context属性用于在成功启动时绑定根WebApplicationContext。
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
}
GenericWebApplicationContext.setServletContext
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
@Override
public void setServletContext(@Nullable ServletContext servletContext) {
this.servletContext = servletContext;
}
}
ServletContextScope
/**
*是ServletContext的包装器,即用于web应用的全局属性。
*这与传统的Spring单例不同,它在ServletContext中公开属性。
*当整个应用程序关闭时,这些属性将被销毁,这可能早于或晚于包含的Spring ApplicationContext的关闭
*/
public class ServletContextScope implements Scope, DisposableBean {
private final ServletContext servletContext;
//破坏回调
private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<>();
}
WebApplicationContextUtils.registerEnvironmentBeans 注册contextParameters、contextAttributes属性对象
主要注册了 contextParameters、contextAttributes属性对象
public abstract class WebApplicationContextUtils {
public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,
@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
}
if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
Map<String, String> parameterMap = new HashMap<>();
if (servletContext != null) {
Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, servletContext.getInitParameter(paramName));
}
}
if (servletConfig != null) {
Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
Collections.unmodifiableMap(parameterMap));
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
Map<String, Object> attributeMap = new HashMap<>();
if (servletContext != null) {
Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
while (attrNameEnum.hasMoreElements()) {
String attrName = (String) attrNameEnum.nextElement();
attributeMap.put(attrName, servletContext.getAttribute(attrName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
Collections.unmodifiableMap(attributeMap));
}
}
}
ServletContextInitializerBeans Servlet上下文初始化对象,触发sevletContext启动相关动作
/**
*从{@link ListableBeanFactory}获取的集合{@link ServletContextInitializer}。
*包括所有的{@link ServletContextInitializer} bean,也适应{@link Servlet},{@link Filter}和某些{@link EventListener} bean。
*<p>项目被排序,使经过调整的bean位于顶部({@link Servlet}, {@link Filter}然后{@link EventListener}),
*而直接的{@link ServletContextInitializer}位于最后。使用{@link AnnotationAwareOrderComparator}对这些组进行进一步的排序。
*/
public class ServletContextInitializerBeans extends AbstractCollection<ServletContextInitializer> {
private static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
private final Set<Object> seen = new HashSet<>();
private final MultiValueMap<Class<?>, ServletContextInitializer> initializers;
private final List<Class<? extends ServletContextInitializer>> initializerTypes;
private List<ServletContextInitializer> sortedList;
//初始化默认类型为ServletContextInitializer
//
public ServletContextInitializerBeans(ListableBeanFactory beanFactory,
Class<? extends ServletContextInitializer>... initializerTypes) {
this.initializers = new LinkedMultiValueMap<>();
this.initializerTypes = (initializerTypes.length != 0) ? Arrays.asList(initializerTypes)
: Collections.singletonList(ServletContextInitializer.class);
//此处添加的是DispatcherServletRegistrationBean
addServletContextInitializerBeans(beanFactory);
//添加自适应Bean
addAdaptableBeans(beanFactory);
//this.initializers =
//key = {Class@4765} "interface javax.servlet.Servlet"
//0 = {DispatcherServletRegistrationBean@7087} "dispatcherServlet urls=[/]"
//key = {Class@4998} "interface javax.servlet.Filter"
//0 = {FilterRegistrationBean@7627} "characterEncodingFilter urls=[/*] order=-2147483648"
//1 = {FilterRegistrationBean@7628} "formContentFilter urls=[/*] order=-9900"
//2 = {FilterRegistrationBean@7629} "requestContextFilter urls=[/*] order=-105"
List<ServletContextInitializer> sortedInitializers = this.initializers.values().stream()
.flatMap((value) -> value.stream().sorted(AnnotationAwareOrderComparator.INSTANCE))
.collect(Collectors.toList());
this.sortedList = Collections.unmodifiableList(sortedInitializers);
logMappings(this.initializers);
}
//getOrderedBeansOfType方法也是从BeanFactory中加载对应类型的bean,此处返回的是DispatcherServletAutoConfiguration自动装配中的DispatcherServletRegistrationBean对象
private void addServletContextInitializerBeans(ListableBeanFactory beanFactory) {
for (Class<? extends ServletContextInitializer> initializerType : this.initializerTypes) {
for (Entry<String, ? extends ServletContextInitializer> initializerBean : getOrderedBeansOfType(beanFactory,
initializerType)) {
//此处添加的是DispatcherServletRegistrationBean
addServletContextInitializerBean(initializerBean.getKey(), initializerBean.getValue(), beanFactory);
}
}
}
//添加了不同类型的上下文初始化Bean,有 Servlet、Filter、Listener等
private void addServletContextInitializerBean(String beanName, ServletContextInitializer initializer,
ListableBeanFactory beanFactory) {
if (initializer instanceof ServletRegistrationBean) {
Servlet source = ((ServletRegistrationBean<?>) initializer).getServlet();
addServletContextInitializerBean(Servlet.class, beanName, initializer, beanFactory, source);
}
else if (initializer instanceof FilterRegistrationBean) {
Filter source = ((FilterRegistrationBean<?>) initializer).getFilter();
addServletContextInitializerBean(Filter.class, beanName, initializer, beanFactory, source);
}
else if (initializer instanceof DelegatingFilterProxyRegistrationBean) {
String source = ((DelegatingFilterProxyRegistrationBean) initializer).getTargetBeanName();
addServletContextInitializerBean(Filter.class, beanName, initializer, beanFactory, source);
}
else if (initializer instanceof ServletListenerRegistrationBean) {
EventListener source = ((ServletListenerRegistrationBean<?>) initializer).getListener();
addServletContextInitializerBean(EventListener.class, beanName, initializer, beanFactory, source);
}
else {
addServletContextInitializerBean(ServletContextInitializer.class, beanName, initializer, beanFactory,
initializer);
}
}
protected void addAdaptableBeans(ListableBeanFactory beanFactory) {
//多媒体文件处理
MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);
addAsRegistrationBean(beanFactory, Servlet.class, new ServletRegistrationBeanAdapter(multipartConfig));
addAsRegistrationBean(beanFactory, Filter.class, new FilterRegistrationBeanAdapter());
for (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes()) {
addAsRegistrationBean(beanFactory, EventListener.class, (Class<EventListener>) listenerType,
new ServletListenerRegistrationBeanAdapter());
}
}
}
DispatcherServletRegistrationConfiguration$DispatcherServletRegistrationBean
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
@Configuration(proxyBeanMethods = false)
@Conditional(DispatcherServletRegistrationCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
@Import(DispatcherServletConfiguration.class)
protected static class DispatcherServletRegistrationConfiguration {
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,
webMvcProperties.getServlet().getPath());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}
}
}
registerListeners检查并注册侦听器bean
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//添加实现ApplicationListener作为侦听器的bean。不影响其他侦听器,可以在不成为bean的情况下添加它们
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
}
finishBeanFactoryInitialization实例化所有剩余的(非lazy-init)单例
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 为此上下文初始化转换服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 如果之前没有注册任何BeanFactoryPostProcessor(例如propertysourcesconfigururer bean),
// 那么注册一个默认的嵌入式值解析器:在这一点上,主要是为了解析注释属性值。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时ClassLoader进行类型匹配。
beanFactory.setTempClassLoader(null);
// 允许缓存所有bean定义的元数据,而不期待进一步的更改。
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons
beanFactory.preInstantiateSingletons();
}
}
DefaultListableBeanFactory.freezeConfiguration&preInstantiateSingletons冻结BeanDefinition、实例化非懒加载单例对象
freezeConfiguration方法冻结了所有的beanDefinition,preInstantiateSingletons方法开始实例化单例对象,具体的实例化过程可参考
SpringBean加载过程中,循环依赖的问题(一)查看一个普通单例Bean的实例化过程
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
}
finishRefresh发布相应的事件
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//完成这个上下文的刷新,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent。
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// 为这个上下文初始化生命周期处理器。
initLifecycleProcessor();
// 首先将刷新事件传播到生命周期处理器
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 进入if逻辑,返回已有的生命周期处理器
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
}
DefaultLifecycleProcessor生命周期处理器
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
//开始bean
private void startBeans(boolean autoStartupOnly) {
//获取生命周期Bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
phases.computeIfAbsent(
phase,
p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
).add(beanName, bean);
}
});
if (!phases.isEmpty()) {
phases.values().forEach(LifecycleGroup::start);
}
}
protected Map<String, Lifecycle> getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
//beanNames :
//0 = "lifecycleProcessor"
//1 = "webServerGracefulShutdown"
//2 = "webServerStartStop"
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle) {
beans.put(beanNameToRegister, (Lifecycle) bean);
}
}
}
return beans;
}
}
WebServerStartStopLifecycle
调用webServerLifecycle的start方法,此处启动了tomcat服务器,调用应用上下文的publishEvent方法,发布ServletWeb服务器已初始化事件
class WebServerStartStopLifecycle implements SmartLifecycle {
public void start() {
this.webServer.start();
this.running = true;
this.applicationContext
.publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
}
}
AbstractApplicationContext.publishEvent
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
}
SimpleApplicationEventMulticaster
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
//根据事件及其事件类型获取对应的监听器,调用invokeListener方法
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
}
SpringApplicationAdminMXBeanRegistrar
public class SpringApplicationAdminMXBeanRegistrar implements ApplicationContextAware, GenericApplicationListener,
EnvironmentAware, InitializingBean, DisposableBean {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationReadyEvent) {
onApplicationReadyEvent((ApplicationReadyEvent) event);
}
if (event instanceof WebServerInitializedEvent) {
onWebServerInitializedEvent((WebServerInitializedEvent) event);
}
}
void onWebServerInitializedEvent(WebServerInitializedEvent event) {
if (this.applicationContext.equals(event.getApplicationContext())) {
this.embeddedWebApplication = true;
}
}
}