这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战」
前言
我们知道:
- SpringBoot简化了开发,因此如果使用SpringBoot来启动Spring的话会简单很多。
但是,根据之前对于SpringBoot启动流程的部分解读,也容易知道SpringBoot的启动流程本质上就是通过一些既定配置来启动Spring容器,本质上还是启动一个Spring的容器。因此,这里我们就来看看Spring的启动过程。
在Spring中,毋庸置疑最重要的是bean,bean的相关内容之前都解析的七七八八了。
其实Spring的启动,最主要的就是辅助bean生成的,例如:
- 绝大多数情况我们都是通过BeanDefinition来生成类的,那么需要有个地方来生成这些BD(扫描)。
- 我们需要有一个BeanFactory,作为bean生成的主要工作情景。
- bean生命周期的PostProcessor也要提前确定。
之前知道的重要的BeanPostProcessor:
BeanPostProcessor:
- AutowiredAnnotationBP(@Autowired)
- CommonAnnotationBP(@Resource)
1.构造方法
我们以这种方式启动容器:
public static void main(String[] args) {
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(XXX.class);
}
由于构造方法是会先执行父类的构造方法,因此上述的构造方法实际上是:
//顺序:从上到下
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
public GenericApplicationContext() {
//流程中的创建bean工厂就在这里
this.beanFactory = new DefaultListableBeanFactory();
}
public AnnotationConfigApplicationContext() {
//监控
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
//这个reader:用来读取
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
//还会添加一些默认的typeFilter
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
//通过前面的reader,把配置类变成beanDeifnition放到对应的map中
register(componentClasses);
refresh();
}
- 上述说的创建bean工厂:
public DefaultListableBeanFactory() {
super();
}
//super指代的父类构造方法
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
//默认是false
if (NativeDetector.inNativeImage()) {
//这里就是构造方法中提到的实例化策略
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
}
}
//上面的super就是这个,是个null
public AbstractBeanFactory() {
}
-
AnnotatedBeanDefinitionReader:
创建好了之后可以:
configApplicationContext.register(XXX.class);就是用这个来实现的,这里会把XXX解析成BD,放到Factory中的beandifnitionMap中。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; //解析conditional注解的 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }在构造reader时也会创建environment和一个condition解析类,而这里会往beanFactory中设置一些东西:
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { registerAnnotationConfigProcessors(registry, null); } public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); //解析配置类的 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }- 这里会把一些必须的beanPostProcessor的beanDefinition,放入beanFactory中。
2.refresh
这里就是启动容器的重中之重了:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//其实是提前处理beanFactory,这个类里没有重写这个hook方法,因此是空
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
//执行beanFactoryPostProcessor,会扫描
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册beanPostProcessor
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
//初始化i18n的相关解析类(messageSource),可以定义对应的bean,没有自定义的话使用默认的
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.
//这里就是bean的实例化的地方了
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//通过上面的广播器去发布事件
//在这里会初始化beanFactory的生命周期processor并发布事件,被下面的start监听
//可以通过类继承SmartLifeCycle来监听该事件,start事件在此发布,stop方法的catch需要isRunning返回了true
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
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.
//给子类的模板【2.1】
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
//验证环境变量中,是否有必须要的key【2.2】
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<>();
}
【2.1】initPropertySources
//比如:子类是GernericApplicationContext
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
//把servletContext中的key-value都放到env中
((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
}
}
但这里示例的AnnotationConfigApplicationContext中没有重写这个方法。
【2.2】验证
我们可以手动启动,方法如下,来指定我们必须的环境变量:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(MockApplication.class);
context.getEnvironment().setRequiredProperties("qwer");
context.refresh();
可以在启动项、properties中设置该变量。
obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//模板方法
refreshBeanFactory();
//简单返回的
return getBeanFactory();
}
//继承的是generic,在这里重写了(还有一个是别的,会销毁bean工厂并重新构造一份)
protected final void refreshBeanFactory() throws IllegalStateException {
//这里看报错也可以知道:如果继承链树上只有这个类,那么只支持刷新一次,如果多次调用了context.refresh,这里就会报错
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
//另一个实现 AbstractRefreshableApplicationContext
protected final void refreshBeanFactory() throws BeansException {
//再次刷新的时候,就会销毁容器,相当于重新启动一次
if (hasBeanFactory()) {
//把有bean销毁逻辑的bean销毁
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
也就是说,支持刷新的context,继承的必须是下面这个,否则就会报错。
- 下面这个类,由于继承的不是generic,因此在前面其实没有实例化beanFactory的 ,上面的流程中也没有,因此这里可以新建一个Bean工厂;前面的在获取之前已经给bean工厂中设置了很多参数。
prepareBeanFactory(beanFactory)
- 设置beanFactory的类加载器,SpringEL表达式解析器,类型转化注册器。
- 添加三个BeanPostprocessor实例
- 记录ignoreDependencyInterface
- 记录ResolvableDependency
- 添加三个单例bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//默认是false,也就是说这里是true
if (!shouldIgnoreSpel) {
//用来解析:类似@Value(#{XXX})方式的
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
//这里可以添加一些默认的类型转换器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//把aware回调的postPoreccesor添加到beanFactory里
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//这里忽略掉的interface,如果继承类被@bean(autowired)定义,那么@Bean的那个地方并不会调用,而只会回调(例子:属性注入部分的autowiredByType),防止多次调用
//因为这里的回调接口,都有set方法
//但是@Autowired还是会调用的,只是在@Bean上不会
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.
// MessageSource registered (and found for autowiring) as a bean.
//这里就是提前加载的bean,后面就不用再去生成了;不用经过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.
//监听【2.3.1】
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
//和aspectJ有关
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.
//把一些初始化好的提前当作bean注册了
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
invokeBeanFactoryPostProcessors && registerBeanPostProcessors
这里的和BeanFactoryPostProcessor有关。
- BeanPostProcessor和这个有关,BPP是bean的后置处理器
- 那么,BFPP就是beanFactory的后置处理器,去处理BeanFactory的。
- 这个接口的重写方法只有postProcessBeanFactory,传入的是beanFactory,可以在这里自定义处理beanFactory以及其中的属性。
- 这个接口的子接口BeanRegistryPP,可以提供往bean工厂添加、修改BeanDefinition的功能。
finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
//类型转换
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));
}
// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
//占位符解析器(${XXX}),这里用的就是前面的environment去解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
//和aspectJ
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 实例化非懒加载单例bean
beanFactory.preInstantiateSingletons();
}
finishRefresh
如下,主要的就是lifeCycle的事件发布:
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
这里就是获取配置的lifeCycleProcessor,获取不到就取默认的。
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
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() + "]");
}
}
}
随后就是调用这个lifeCycle的onRefresh方法,默认对应的方法栈如下:
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
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);
}
});
//这里跟分组有关系,在getPhase中定义
if (!phases.isEmpty()) {
phases.values().forEach(LifecycleGroup::start);
}
}
//这里是获取lifeCycle的bean
protected Map<String, Lifecycle> getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
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);
//但这里又需要是SmartLifeCycle的,因此必须实现了SmartLifeCycle,这里才会使用
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;
}
事件发布相关
在前面和事件发布相关比较重要的发布相关组件(不包括事件处理的)有:
- ApplicationListenerDetector - 这个BPP会把是applicationListener的,注册到context的ApplicationContext中(context.addApplicationListener)
- SimpleApplicationEventMulticaster - 发布器
- EventListenerMethodProcessor - 处理@EventListener注解的
- 这个接口继承了SmartInitializingSingleton,会在所有非懒加载的单例bean执行完后再执行。
- 这个类中继承的接口,会将bean工厂中的所有bean取出,一个个地查找被**@EventListener**注解修饰的;如果有,那么就存起来。
- 收集好之后,会被封装为ApplicationListener,注册到context的ApplicationContext中(context.addApplicationListener)
- DefaultEventListenerFactory
- 上面的@EventListener,是在这里被封装成ApplicationListener的。
事件监听器可以有以下的几种方式,来生成自定义的:
- implements ApplicationListener
- 这个不管是不是@Lazy,都会被调用,因为源码中主动去获取了
- 在某个方法上加**@EventListener**,但入参必须是ApplicationEvent。