阅读目录
[refresh()调用的核心方法预览]
[prepareRefresh()]
[obtainFreshBeanFactory()]
[this.prepareBeanFactory(beanFactory);]
[postProcessBeanFactory(beanFactory);]
[invokeBeanFactoryPostProcessors(beanFactory);]
[finishBeanFactoryInitialization(beanFactory)]
概述
在学习springboot时候,会牵涉到很多的知识,而refresh方法可以说其中的核心方法,为什么这么说,因为整个spring的核心aop和ioc都和这个方法有关,既然这个方法那么重要,那我们就分析一下这个方法到底干了什么。
refresh()调用的核心方法预览
image看了上面这个图是不是都晕了,其实不用晕,这里面很多的方法只是在做一些准备的工作和监听的工作,真正核心的就两三个方法,那我就把核心的方法先列出来,
invokeBeanFactoryPostProcessors(beanFactory),核心方法,将程序中的所有bean放入到beanDefinitionMap中,注意这一步并没有实例化bean,而是获得bean的beanDefinition
finishBeanFactoryInitialization(beanFactory),核心方法,将上面放入到beanDefinitionMap中的非懒加载的bean都实例化,这两个方法可以说是让ioc起作用的核心方法
其实核心的方法我觉得就这两个,剩下的都是一些准备性的工作,ok,下面我们就逐个分析一下每个方法,不重要的方法我就简单说一下,我觉得没必要每个方法都全部吃透,搞明白核心方法就可以了,spring代码那么多,又不是自己要去写一个spring,没必要全部吃透。
prepareRefresh()
这个方法,从名字就可以看出来,就是一个为了执行refresh()方法做准备的方法,下面我们看一下代码
protectedvoidprepareRefresh() {
//设置开始时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if(this.logger.isDebugEnabled()) {
if(this.logger.isTraceEnabled()) {
this.logger.trace("Refreshing " +this);
} else {
this.logger.debug("Refreshing " +this.getDisplayName());
}
}
this.initPropertySources();
//校验一些关键的环境信息是否存在
this.getEnvironment().validateRequiredProperties();
if(this.earlyApplicationListeners ==null) {
this.earlyApplicationListeners =newLinkedHashSet(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents =new LinkedHashSet();
}
总结:这个方法总的来说就是设置了一下启动的时间,校验了一下环境参数。
obtainFreshBeanFactory()
这个方法从名称也可以看出来获取beanFactory的,至于beanFactory是什么,相信大家也应该清楚,整个spring的核心接口,用于生产bean,为他的实现类DefaultListableBeanFactory,ApplicationContext等提供了最基本的规范,下面看一下代码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
returnthis.getBeanFactory();
}
第一个方法refreshBeanFactory,这个方法就是未beanFactory设置了一个序列化id,我们主要看一下第二个,这里使用了模板模式,真是实现这个getBeanFactory()的是GenericApplicationContext(),我们看一下这个类的构造方法
public GenericApplicationContext() {
this.customClassLoader =false;
this.refreshed =newAtomicBoolean();
//这里new了一个beanFactory
this.beanFactory =new DefaultListableBeanFactory();
}
我们看一下this.getBeanFactory();方法代码
public final ConfigurableListableBeanFactory getBeanFactory() {
returnthis.beanFactory;
}
总结:obtainFreshBeanFactory()方法就是为了返回new DefaultListableBeanFactory();
this.prepareBeanFactory(beanFactory);
同样,从名字就可以看出来是为beanFactory做一些准备工作,因为上一步已经获取到beanFactory
protectedvoid prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(newResourceEditorRegistrar(this,this.getEnvironment()));
//这里设置了一个beanPostProcessor,这个接口的作用后面再说,这个接口和AOP有关beanFactory.addBeanPostProcessor(
newApplicationContextAwareProcessor(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.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class,this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class,this);
beanFactory.registerResolvableDependency(ApplicationContext.class,this);
beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));
if(beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if(!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment",this.getEnvironment());
}
if(!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties",this.getEnvironment().getSystemProperties());
}
if(!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment",this.getEnvironment().getSystemEnvironment());
}
}
总结:这个里面代码一大坨,基本就是向beanFactory中设置了一个属性,为了后面使用。
postProcessBeanFactory(beanFactory);
这个方法在这里并没有实现,而是交给了子类实现,这里就不分析了
invokeBeanFactoryPostProcessors(beanFactory);
这个就是核心方法了,看一下代码
protectedvoid invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if(beanFactory.getTempClassLoader() ==null&& beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
这个代码很长,但是大家不要怕,里面很多个循环只是在做重复的事情
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
Set processedBeans =new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9; ArrayList currentRegistryProcessors;
String[] postProcessorNames;
//先判断beanFactory是不是实现了BeanDefinitionRegistry
if(beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
regularPostProcessors =new ArrayList();
registryProcessors =new ArrayList();
Iterator var6 = beanFactoryPostProcessors.iterator();
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor =(BeanFactoryPostProcessor)var6.next();
//判断postProcessor是不是BeanDefinitionRegistryPostProcessor,这个接口继承了BeanFactoryPostProcessor
if(postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor)postProcessor;
//执行方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); }
else {
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors =newArrayList();
//获取beanFactory中实现了BeanDefinitionRegistryPostProcessor接口的beanpostProcessorNames
= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false);
String[] var16 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //对postProcessor排序 sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors);
//<1.1>,执行postProcessor的postProcessBeanDefinitionRegistry()方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//执行完了之后,清空当前的后置处理器列表currentRegistryProcessors.clear();
//<1.2>这一步和上一步的过程一样,但是这里获取到的这个处理器非常重要,是ConfigurationClassPostProcessor,这个类会处理所有的bean,并把其beanDefinition放入beanDefinitionMap中postProcessorNames
= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
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);
currentRegistryProcessors.clear();
booleanreiterate =true;
while(reiterate) {
reiterate =false;
//这里的过程依然是一样的,把所有的postProcessor都执行一遍postProcessorNames
= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for(intvar26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
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);
currentRegistryProcessors.clear();
}
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class,true,false);
regularPostProcessors =new ArrayList();
registryProcessors =new ArrayList();
currentRegistryProcessors =new ArrayList();
postProcessorNames = postProcessorNames;
intvar20 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var20; ++var9) {
ppName = postProcessorNames[var9];
if(!processedBeans.contains(ppName)) {
if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} elseif(beanFactory.isTypeMatch(ppName, Ordered.class)) {
registryProcessors.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(regularPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List orderedPostProcessors =new ArrayList(registryProcessors.size());
Iterator var21 = registryProcessors.iterator();
while(var21.hasNext()) {
String postProcessorName = (String)var21.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List nonOrderedPostProcessors =new ArrayList(currentRegistryProcessors.size());
Iterator var24 = currentRegistryProcessors.iterator();
while(var24.hasNext()) {
ppName = (String)var24.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
image
这个方法中写了很多的循环,每个循环干了什么事情呢?
找出beanFactory中所有的实现了BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的bean
对找出来的postProcessor进行排序
执行postProcessor中的postProcessBeanDefinitionRegistry()方法和postProcessBeanFactory()方法
那估计大家都有疑问了,为什么要写那么多循环,一个循环不就ok了,我自己觉得写一个中间那个while(reiterate)就可以了,没搞明白spring为什么要在这个while之前还要搞两个循环
<1.1>处代码
imageprivate static void invokeBeanDefinitionRegistryPostProcessors(Collection postProcessors, BeanDefinitionRegistry registry) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanDefinitionRegistryPostProcessor postProcessor =(BeanDefinitionRegistryPostProcessor)var2.next();
//就是调用每个postProcessor中的方法 postProcessor.postProcessBeanDefinitionRegistry(registry); } }
![image](https://img.haomeiwen.com/i25923643/ac7904603b793a90.gif?imageMogr2/auto-orient/strip)
<1.2>处代码,ConfigurationClassPostProcessor,我们看一下这个类的回调函数
![image](https://img.haomeiwen.com/i25923643/a00d9deb18127ef4.gif?imageMogr2/auto-orient/strip)
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if(this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
} else if(this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
} else{
this.registriesPostProcessed.add(registryId);
//执行这里的代码
this.processConfigBeanDefinitions(registry);
}
}
![image](https://img.haomeiwen.com/i25923643/c0c2c7a6af830e04.gif?imageMogr2/auto-orient/strip)
进入this.processConfigBeanDefinitions(registry);
![image](https://img.haomeiwen.com/i25923643/fdc7e3858769a4a3.gif?imageMogr2/auto-orient/strip)
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List configCandidates =new ArrayList();
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if(beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) !=null) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
} else if(ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef,this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
if(!configCandidates.isEmpty()) {
configCandidates.sort((bd1, bd2) -> {
inti1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
inti2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr =null;
if(registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry)registry;
if(!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if(generator !=null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if(this.environment ==null) {
this.environment =new StandardEnvironment();
}
ConfigurationClassParser parser =newConfigurationClassParser(this.metadataReaderFactory,this.problemReporter,this.environment,this.resourceLoader,this.componentScanBeanNameGenerator, registry);
Set candidates =new LinkedHashSet(configCandidates);
HashSet alreadyParsed =new HashSet(configCandidates.size());
do{
//这里就是解析每个beanparser.parse(candidates); parser.validate(); Set
configClasses =new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if(this.reader ==null) {
this.reader =newConfigurationClassBeanDefinitionReader(registry,this.sourceExtractor,this.resourceLoader,this.environment,this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if(registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set oldCandidateNames =new HashSet(Arrays.asList(candidateNames));
Set alreadyParsedClasses =new HashSet();
Iterator var12 = alreadyParsed.iterator();
while(var12.hasNext()) {
ConfigurationClass configurationClass = (ConfigurationClass)var12.next();
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
String[] var23 = newCandidateNames;
int var24 = newCandidateNames.length;
for(int var14 = 0; var14 < var24; ++var14) {
String candidateName = var23[var14];
if(!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if(ConfigurationClassUtils.checkConfigurationClassCandidate(bd,this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
} while(!candidates.isEmpty());
if(sbr !=null&& !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if(this.metadataReaderFactoryinstanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
}
}
}
image
有兴趣的可以进入parse看一下,这个就是我们每次写程序写了很多的@Service,@Component,@Controller,都是这里解析的
[finishBeanFactoryInitialization(beanFactory)]
由于中间几个方法都不重要,就不分析了,直接分析这个方法
imageprotected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if(!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,false,false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null); beanFactory.freezeConfiguration();
//这一步就是将所有的非懒加载的bean初始化的步骤beanFactory.preInstantiateSingletons(); }
image
进入beanFactory.preInstantiateSingletons();
image imagepublic void preInstantiateSingletons()throws BeansException {
if(this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " +this);
}
List beanNames =newArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if(!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance =this.getSingleton(beanName);
if(singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if(System.getSecurityManager() !=null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd =this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if(this.isFactoryBean(beanName)) {
bean =this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean factory = (FactoryBean)bean;
boolean isEagerInit;
if(System.getSecurityManager() !=null&& factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit,this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
image
这个方法,真是出奇的长,写的非常神奇,我还从没有写过这么多的循环嵌套,这个方法总的来说其实就是调用beanFactory.getBean()方法进行实例化bean,细节我是真没看头大
总结:这个方法非常重要,尤其是getBean方法,这个方法下一篇文章会分析
最后
一开始的打算是把每个方法仔细分析一遍,在分析的过程中发现确实没有多大必要,里面的逻辑写的太多,把核心的看一下就可以了,其实这个refresh()方法我写的比较简单,其实里面的逻辑还是挺多的。下一篇文章介绍getBean()方法
问到这个流程,记录下来,确实非常有用。
网友评论