Spring
2020-11-03 22:21:11 0 举报
Spring
作者其他创作
大纲/内容
getEnvironment().validateRequiredProperties();校验必填属性 PropertySourcesPropertyResolver:父类中有属性requiredProperties;看是什么时候放进去的
initMessageSource();
finishRefresh();
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(\"environment\
invokeBeanFactoryPostProcessors(beanFactory);
生命周期第七步:上下文失败
4:ApplicationPreparedEventcontextLoaded:先将监听器加入上下文,如果监听器是ApplicationContextAware,则将上下文注入;多播器派发入口:App.prepareContext之中
第一次:加载了大部分配置的Bean第二次:取出 BeanDefinitionRegistryPostProcessor,然后过滤出前面没有执行过的,并且是Order的Bean定义注册增强器,执行与第一次相同的逻辑:排序,标记已运行,执行postProcessBeanDefinitionRegistry,清空临时列表。(PriorityOrdered 也是Order,所以如果第一次没有加载到的,本次也会补上)暂时没有发现系统自带的第三次:取出BeanDefinitionRegistryPostProcessor,只要不在前面两次执行范围之内的,执行与第一次类似的逻辑,但是会循环执行,直到取不出新的:想Mappper、以及自定义的普通BeanFactory***会在这里命中,暂时没有发现系统自带的
refreshContext(context);refresh(context);if (this.registerShutdownHook) {context.registerShutdownHook();}
// 计时器:开始StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();// 设置系统变量:java.awt.headless,如果没有默认为true(这个属性有何特殊之处?)configureHeadlessProperty();
取出Bean定义数据: org.springframework.context.annotation.internalConfigurationAnnotationProcessor,为其添加属性“metadataReaderFactory”为刚定义的Bean
之后是按照优先级执行BeanDefinitionRegistryPostProcessor
如果最新解析后的Bean定义数量大于旧的(名称)数量:先获取所有新的Bean名称,如果新的Bean不包含在旧的名称里面,新的Bean又是Configuration类,同时又不在刚才解析过的Configuration类里面,则把这个类的定义信息加入 candidates;加完之后就的Bean名称换新的Bean名称,继续循环。直到没有了,跳出循环
计时:初始化系统属性:java.awt.headless
configureIgnoreBeanInfo(environment);spring.beaninfo.ignore;如果没有设置,默认为trueBanner printedBanner = printBanner(environment);打印Banner,可以设置模式Banner.Mode.OFF\\Mode.LOGSpringApplicationBannerPrinterDEFAULT_BANNER_LOCATION = \"banner.txt\"\"spring.banner.location\"、\"spring.banner.image.location\"
destroyBeans();
生命周期第四步:上下文加载好
SpringApplicationRunListeners listeners = getRunListeners(args);这个类组织了所有的监听器:没有是成员变量,而是作为参数传到各个方法中,管控应用生命周期starting、environmentPrepared、contextPrepared、contextLoaded、started、running、failed
6:ApplicationStartedEvent入口:App.stopWatch之后,通过context.publishEvent交给Context
生命周期第三步:上下文准备好
return getBeanFactory();GenericApplicationContext 直接返回了这个对象;现在这个对象里面的内容还是很少: boot中生成的哪些;追一下ignoredDependencyInterfaces什么时候生成以及如何作用
propertySources.addLast(new PropertiesPropertySource(\"systemProperties\
优先级最高:此时不是立即执行:在refresh过程postProcessBeanFactoryCachingMetadataReaderFactoryPostProcessor.postProcessBeanDefinitionRegistry
defaultRetriever.applicationListenersdefaultRetriever.applicationListenerBeans(只是记录了Bean名字,从beanFactory内解析,如果不是单例,继续记录名字)从以上两个列表内汇总支持的监听器,依据是AbstractApplicationEventMulticaster.span style=\"font-size: inherit;\
0:ApplicationFailedEvent发生异常
CachingMetadataReaderFactoryPostProcessorConfigurationWarningsPostProcessor先调用:registryProcessor.postProcessBeanDefinitionRegistry(registry);再加入:registryProcessors
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();所以这个步骤给BeanFacory设置了一个ID,然后返回
beanFactory instanceof BeanDefinitionRegistry
processConfigBeanDefinitions(registry);
ConfigurableApplicationContext applicationContext = SpringApplication.run(args);这是Spring jar(内置tomcat)包应用启动的入口
BeanDefinitionRegistryPostProcessor
9:ContextClosedEvent入口好像只有Context
参数BeanFactoryPostProcessor分成两类
String[] candidateNames = registry.getBeanDefinitionNames();取出所有Bean定义名称:然后循环取出Bean定义信息;\"full\"、\"lite\"任意一个匹配从Bean信息中获取属性“org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass”说明已经加载过了,否则 checkConfigurationClassCandidate
loadTimeWeaverif (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
prepareRefresh();
生命周期第六步:上下文运行当中
生命周期第五步:上下文启动了:过后
parser.validate();Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed); // 又解析出300多个Configuration类
protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new StubPropertySource(\"servletConfigInitParams\")); propertySources.addLast(new StubPropertySource(\"servletContextInitParams\")); if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { propertySources.addLast(new JndiPropertySource(\"jndiProperties\")); } super.customizePropertySources(propertySources);}
加入一个循环:跳出条件是 !candidates.isEmpty():同时candidates就是最开始的入口类
校验只能是首次执行this.registriesPostProcessed.contains(registryId)、this.factoriesPostProcessed.contains(registryId)this.registriesPostProcessed.add(registryId)
resetCommonCaches
AbstractApplicationContext.refresh
initApplicationEventMulticaster();
否
parser.parse(candidates);第一轮方法下来:metadataReaderFactory资源中缓存了500多个类资源信息;registry中多了200多个Bean定义信息
设置状态:不关闭、激活;打印日志this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true);
prepareBeanFactory(beanFactory);所以这个步骤添加了感知后置增强,监听器Bean装饰后存入CXT;把环境相关的几个Bean注册单例;第一步的两个属性,ignoreDependencyInterface,registerResolvableDependency有什么作用?
BeanFactoryPostProcessor
listeners.starting();这是生命周期的第一步,对应事件 ApplicationStartingEvent
3:ApplicationContextInitializedEventcontextPrepared:多播器派发入口:App.prepareContext之中
优先级最低 - 1;不是立即执行:在refresh过程postProcessBeanFactory中ConfigurationWarningsPostProcessor.postProcessBeanDefinitionRegistry
5:ContextRefreshedEvent通过App.refreshContext转入Context
throw ex;
beanDef.getBeanClassName() == null || beanDef.getFactoryMethodName() != null如果是工厂Bean就直接返回False
onRefresh();
PropertySourceOrderingPostProcessor加入:regularPostProcessors
postProcessBeanFactory(beanFactory);
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);
listeners.started(context);
this.metadataReaderFactory清除缓存if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}
7:ApplicationReadyEvent入口:App.callRunners之后,通过context.publishEvent交给Context
static WebApplicationType deduceFromClasspath() { if (ClassUtils.isPresent(\"org.springframework.web.reactive.DispatcherHandler\
生命周期第二步:环境准备好
listeners.running(context);
// super.setEnvironment(environment);// this.reader.setEnvironment(environment);// this.scanner.setEnvironment(environment);context.setEnvironment(environment);// this.beanNameGenerator 、this.resourceLoader// context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());postProcessApplicationContext(context);// SpringApplication 构造器中加载的6个ApplicationContextInitializer,循环 initializer.initialize(context)// 6个构造器的作用看文档(语雀)applyInitializers(context);listeners.contextPrepared(context);// 打印日志if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context);}// 注册一些boot个性化Bean,参数,打印标志ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton(\"springApplicationArguments\
SpringApplication.run(args)
通过ComponentScanPackageCheck能找到当前应用扫描路径,Set<String> scannedPackages = getComponentScanningPackages(registry);
这里有生命周期第二步骤
添加一个Bean(SharedMetadataReaderFactoryBean)名为 \"org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory\"
registerListeners();
cancelRefresh(ex);
// 通过解析出来的Configuration类,又增加了Bean定义信息(一共500多个)this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);candidates.clear();
refreshBeanFactory();CAS保证方法只被调用一次,DefaultListableBeanFactory在boot里面初始化过this.beanFactory.setSerializationId(getId());
this.earlyApplicationEvents = new LinkedHashSet<>();
2:ApplicationEnvironmentPreparedEventenvironmentPrepared:多播器派发入口:App.prepareEnvironment之中
SpringApplication.getSpringFactoriesInstances
span style=\"font-size: inherit;\
ExitCodeEvent
if (bean instanceof Aware) {\t\t\tif (bean instanceof EnvironmentAware) {\t\t\t\t((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());\t\t\t}\t\t\tif (bean instanceof EmbeddedValueResolverAware) {\t\t\t\t((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);\t\t\t}\t\t\tif (bean instanceof ResourceLoaderAware) {\t\t\t\t((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);\t\t\t}\t\t\tif (bean instanceof ApplicationEventPublisherAware) {\t\t\t\t((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);\t\t\t}\t\t\tif (bean instanceof MessageSourceAware) {\t\t\t\t((MessageSourceAware) bean).setMessageSource(this.applicationContext);\t\t\t}\t\t\tif (bean instanceof ApplicationContextAware) {\t\t\t\t((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);\t\t\t}\t\t}
// 这个PostProcesser是上下文感知器:当Bean实现了指定接口,会将容器对象注入进去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);
逻辑同
context = createApplicationContext();如果指定 applicationContextClass,直接生成,否则span style=\"font-size: inherit;\
原来加载的this.applicationListeners放入this.earlyApplicationListeners
然后看他们是否有警告信息:List<String> problematicPackages = getProblematicPackages(scannedPackages);如果有:打印Warn日志
// getOrder 值越大,优先级越低AnnotationAwareOrderComparator.sort(instances);return instances;
AbstractApplicationEventMulticaster.getApplicationListeners(SimpleApplicationEventMulticaster)
1:ApplicationStartingEventstarting: 多播器派发入口:App.getRunListeners之后
收藏
收藏
0 条评论
下一页