【Spring源码解读三】IoC容器之AnnotationConfigApplication的refresh()刷新方法其二

news/2024/11/25 9:26:58/

invokeBeanFactoryPostProcessors()

PriorityOrdered接口

Ordered接口

invokeBeanDefinitionRegistryPostProcessors()

registerBeanPostProcessors()

getBeanNamesForType()

initMessageSource()

initApplicationEventMulticaster()

onRefresh()

registerListeners()

finishBeanFactoryInitialization()

finishRefresh()

参考文献


上个博文已经记录了refresh()的前四个方法作用,也就是

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 刷新上下文prepareRefresh();// 告诉子类刷新内部 Bean工厂// 在这个方法中主要是获取 DefaultListableBeanFactory 这个Bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 准备Bean工厂以便在此上下文中使用prepareBeanFactory(beanFactory);try {// 允许在上下文子类中对bean工厂进行后处理postProcessBeanFactory(beanFactory);// 这篇博文主要先记录后八个步骤// 调用在上下文中注册为bean的工厂处理器(重要)// 注解开发对包进行扫描得到Bean的定义invokeBeanFactoryPostProcessors(beanFactory);// 注册拦截bean创建的bean处理器 如果没有BeanProcessors 此步骤什么也不做registerBeanPostProcessors(beanFactory);// 初始化此上下文的消息源// 将messageSource这个Bean对象放到beanFactory中的singletonObjects中initMessageSource();// 初始化此上下文的事件多播// 将applicationEventMulticaster这个Bean对象放到beanFactory中的singletonObjects中initApplicationEventMulticaster();// 初始化特定上下文子类中的其他特殊beanonRefresh();// 检查侦听器bean并注册它们// 在所有Bean中查找Listener这个Bean对象并注册到消息广播中 没有的话什么也不做registerListeners();// 实例化所有剩余的(非惰性初始化)单例  重要finishBeanFactoryInitialization(beanFactory);// 初始化并刷新生命周期处理器finishRefresh();} catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// 销毁已创建的singleton以避免挂起资源destroyBeans();// 重置“活动”标志cancelRefresh(ex);// 向调用方传播异常throw ex;} finally {// 重置Spring核心中的常见内省缓存,因为我们可能不再需要单例bean的元数据resetCommonCaches();}}
}

invokeBeanFactoryPostProcessors()

        这里主要去看PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法,此方法内部主要是调用Bean工厂的后置处理器发挥作用。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 调用Bean工厂的后置处理器发挥作用 接下来进入这个方法的源码中阅读PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// 检测LoadTimeWeaver并准备编织(如果同时发现)// 例如,通过ConfigurationClassPostProcessor注册的@Bean方法) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}

        进入这个方法首先需要知道两个接口。第一个是BeanFactoryPostProcessor:用来修改Spring容器中已经存在的bean的定义,使用ConfigurableListableBeanFactory对bean进行处理。第二个是BeanDefinitionRegistryPostProcessor:继承BeanFactoryPostProcessor,作用跟BeanFactoryPostProcessor一样,只不过是使用BeanDefinitionRegistry对bean进行处理。

以下六步是这个方法内部的实现逻辑。

        第一步是实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor找出来,然后排序后依次执行;

        第二步是实现Ordered接口的BeanDefinitionRegistryPostProcessor找出来,然后排序后依次执行;

        第三步是实现其它接口的BeanDefinitionRegistryPostProcessor找出来执行并依次执行。

        第三步是实现PriorityOrdered接口的BeanFactoryPostProcessor找出来,然后排序后依次执行;

        第四步是实现Ordered接口的BeanFactoryPostProcessor找出来,然后排序后依次执行;

        第五步是实现其它接口的BeanFactoryPostProcessor找出来执行并依次执行。

        第六步是清除缓存clearMetadataCache()。

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;// 存放Bean工厂后置处理器的链表List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();// 存放Bean描述注册后置处理器的链表List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();// 遍历存放Bean工厂后置处理器的链表for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);} else {regularPostProcessors.add(postProcessor);}}// 这里不要初始化FactoryBeans:我们需要保持所有常规bean未初始化,以便让bean工厂的后处理器应用于它们!// 在实现PriorityOrdered、Ordered和其他的BeanDefinitionRegistryPostProcessors之间分离。List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors。String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// 在调试时返回的postProcessorNames是org.springframework.context.annotation.internalConfigurationAnnotationProcessorfor (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); // 将第二个存放BeanDefinitionRegistryPostProcessor的链表的元素放到第一个链表中// 调用PostProcessors 此方法会在下面进行介绍invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear(); // 清空currentRegistryProcessors链表// 其次,调用实现Ordered的BeanDefinitionRegistryPostProcessors。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);currentRegistryProcessors.clear();// 最后,调用所有其他BeanDefinitionRegistryPostProcessors,直到不再出现其他处理器为止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);currentRegistryProcessors.clear();}// 现在,调用迄今为止处理的所有处理器的postProcessBeanFactory回调invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);} else {// 调用在上下文实例中注册的工厂处理程序invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 这里不要初始化FactoryBeans:我们需要保持所有常规Bean未初始化,以便让Bean工厂的后处理器应用于它们!String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// 在实现PriorityOrdered、Ordered和其他的BeanFactoryPostProcessors之间分离。List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// 跳过-已在上面的第一阶段中处理} 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);}}// 首先,调用实现PriorityOrdered的BeanFactoryPostProcessors。sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// 其次,调用实现Ordered的BeanFactoryPostProcessors。List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 最后,调用其它所有的BeanFactoryPostProcessorsList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// 清除缓存的合并bean定义,因为后处理程序可能已经修改了原始元数据,例如替换了值中的占位符// 1、将AbstractBeanFactory的mergedBeanDefinitions(Map)其中的值RootBeanDefinition中的stale设为true// 2、将DefaultListableBeanFactory的mergedBeanDefinitionHolders、allBeanNamesByType、singletonBeanNamesByType三个Map集合清空beanFactory.clearMetadataCache();
}

        这里我认为需要做笔记学习一下PriorityOrdered接口与Ordered接口的作用。

PriorityOrdered接口

        PriorityOrdered接口源码没有方法,只是实现了Ordered接口。并且有很多类实现了这个接口。

public interface PriorityOrdered extends Ordered {
}

Ordered接口

        Ordered接口源码,很简短,就定义了一个Ordered接口,然后两个常量,分别对应最高级(数值最小)和最低级(数值最大),也就是数值越小,等级越高,数值越大,等级越低,然后有一个getOrder()方法返回排序值。

        这个接口主要是配合@Order注解。两者的作用是定义Spring IOC容器中Bean的执行顺序的优先级,Bean的加载顺序不受@Order或Ordered接口的影响;而Ordered接口,用来排序的。Spring是一个大量使用策略设计模式的框架,这意味着有很多相同接口的实现类,那么必定会有优先级的问题。于是,Spring就提供了Ordered这个接口,来处理相同接口实现类的优先级问题。getOrder()值越小,优先级越高。一般用于AOP事务执行顺序

public interface Ordered {// 用于最高优先级值的有用常量int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;// 用于最低优先级值的有用常量int LOWEST_PRECEDENCE = Integer.MAX_VALUE;/*** 获取该对象的order值。* <p>较高的值被解释为较低的优先级。作为结果,* 值最低的对象具有最高优先级(有点* 类似于Servlet {@ code-on-startup}值)。* <p>相同的order值将导致受影响的对象任意排序位置* @return 排序值* @see #HIGHEST_PRECEDENCE* @see #LOWEST_PRECEDENCE*/int getOrder();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {// Order的值int value() default Ordered.LOWEST_PRECEDENCE;
}

invokeBeanDefinitionRegistryPostProcessors()

        接下来就先看这个方法的最后一行,也就是实际处理配置类Bean定义的方法。由于其源码太多就不copy出来了,主要是对配置类的注解进行处理处理配置类的Bean的定义,将配置类中的Bean放置BeanDefinitionRegistry下的beanDefinitionMap中。

/*** 调用给定的BeanFactoryPostProcessor bean。*/
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {for (BeanFactoryPostProcessor postProcessor : postProcessors) {postProcessor.postProcessBeanFactory(beanFactory);}
}// 紧接着调用父类BeanDefinitionRegistryPostProcessor的方法
// 其有多个实现类 但是进入到了ConfigurationClassPostProcessor类进行实现
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {int factoryId = System.identityHashCode(beanFactory);if (this.factoriesPostProcessed.contains(factoryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);}this.factoriesPostProcessed.add(factoryId);if (!this.registriesPostProcessed.contains(factoryId)) {// 主要是看这个方法processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);}enhanceConfigurationClasses(beanFactory);beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}/*** 从注册表中的配置类派生更多的bean定义。*/
@Override
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);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);}this.registriesPostProcessed.add(registryId);// 下面这个方法是重点 但源码太多不适合展示processConfigBeanDefinitions(registry);
}

registerBeanPostProcessors()

        注册拦截bean创建的bean处理器。在这里面主要是做了三件事情。

1、先找出实现了PriorityOrdered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中。

2、找出实现了Ordered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中。

3、没有实现PriorityOrdered和Ordered接口的BeanPostProcessor加到BeanFactory的BeanPostProcessor集合中。

/*** 实例化并注册所有BeanPostProcessor bean,如果给定,则遵循显式顺序。* 必须在应用程序bean的任何实例化之前调用。*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 此方法会在下面进行介绍String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// 注册BeanPostProcessorChecker,当在BeanPostProcessor实例化期间创建bean时,即当bean不适合由所有BeanPostProcessors处理时,该Checker会记录信息消息int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// 在实现PriorityOrdered、Ordered和其他的BeanPostProcessors之间分离。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)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);} else {nonOrderedPostProcessorNames.add(ppName);}}// 首先,注册实现PriorityOrdered的BeanPostProcessors。sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// 接下来,注册实现Ordered的BeanPostProcessors。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);// 现在,注册所有常规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);// 最后,重新注册所有内部BeanPostProcessors。sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// 将用于检测内部bean的后处理器重新注册为ApplicationListeners,将其移动到处理器链的末端(用于拾取代理等)。beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

getBeanNamesForType()

        从上面PostProcessorRegistrationDelegate类的registerBeanPostProcessors()方法中,第一行代码就是进入getBeanNamesForType()方法,而这个方法是由几个实现类实现的,而基于前面IoC容器刷新的第二个方法中就是获取DefaultListableBeanFactory这个对象。所以会进入到这个类。先看结果:获取到了internalAutowiredAnnotationProcessorinternalCommonAnnotationProcessor这两个对象。下面的截图就是beanDefinitionNames列表中的值。

private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {List<String> result = new ArrayList<>();// 检查所有bean定义for (String beanName : this.beanDefinitionNames) {// 只有当bean名称没有定义为其他bean的别名时,才认为bean是合格的if (!isAlias(beanName)) {try {RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 只有在bean定义完成时才检查它if (!mbd.isAbstract() && (allowEagerInit ||(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&!requiresEagerInitForType(mbd.getFactoryBeanName()))) {boolean isFactoryBean = isFactoryBean(beanName, mbd);BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();boolean matchFound = false;boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();if (!isFactoryBean) {if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);}} else  {if (includeNonSingletons || isNonLazyDecorated ||(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);}if (!matchFound) {// 在FactoryBean的情况下,接下来尝试匹配FactoryBean实例本身beanName = FACTORY_BEAN_PREFIX + beanName;matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);}}if (matchFound) {result.add(beanName);}}} catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {if (allowEagerInit) {throw ex;}// 可能是一个占位符:出于类型匹配的目的,让我们忽略它LogMessage message = (ex instanceof CannotLoadBeanClassException) ?LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName);logger.trace(message, ex);onSuppressedException(ex);}}}
}

initMessageSource()

        初始化MessageSource组件(做国际化功能;消息绑定,消息解析),这个接口提供了消息处理功能。主要用于国际化/i18n。在这方法中主要是在上下文初始化注册、messageSource的Bean。将此Bean对象放到beanFactory的singletonObjects对象中。

/*** 工厂中 MessageSource bean的名称。* 如果未提供,则将消息解析委派给父级。* @see MessageSource*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";/*** 初始化MessageSource。如果在此上下文中未定义,请使用父级的。*/
protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// 使MessageSource知道父MessageSourceif (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// 如果尚未注册任何父MessageSource,则仅将父上下文设置为父MessageSource。hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isTraceEnabled()) {logger.trace("Using MessageSource [" + this.messageSource + "]");}} else {// 使用空的MessageSource可以接受getMessage调用。DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;// 在这步将messageSource这个Bean对象放到beanFactory中的singletonObjects中beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isTraceEnabled()) {logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");}}
}

initApplicationEventMulticaster()

        在这方法中主要是在上下文初始化注册AppplcationEventMulticaster的Bean。应用消息广播。将此Bean对象放到beanFactory的singletonObjects对象中。

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()

protected void onRefresh() throws BeansException {// 对于子类中才进行操作 否则默认情况下不执行任何操作
}

registerListeners()

protected void registerListeners() {// 首先注册静态指定的侦听器for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 不要在这里初始化FactoryBeans:我们需要保持所有常规bean未初始化,以便让后处理器应用于它们!String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// 发布早期的应用程序事件,现在我们终于有了多主机Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}
}

finishBeanFactoryInitialization()

        由于这个方法内的源码较多,可以先看这个方法执行结束后在beanFactory的singletonObjects中存放了什么对象,可以看到存放了在配置类中定义的bean对象(user)。我打算将这个方法的源码放到下一个文章在进行描述。

finishRefresh()

protected void finishRefresh() {// 清除上下文级资源缓存(如扫描中的ASM元数据)// 对应的就是resourceCaches这个ConcurrentHashMap的清空clearResourceCaches();// 初始化此上下文的生命周期处理器initLifecycleProcessor();// 首先将刷新传播到生命周期处理器getLifecycleProcessor().onRefresh();// 发布最终事件publishEvent(new ContextRefreshedEvent(this));// 参与LiveBeansView MBean(如果活动)LiveBeansView.registerApplicationContext(this);
}

        以上就是refresh()方法的后八个方法的源码剖析,当然,并没有那么深度的进行剖析,毕竟本人水平有限,再加上太深度的剖析会导致文字量太大。还有个finishBeanFactoryInitialization()方法,也就是try语句块的倒数第二个方法,就放到下一篇博文了。

参考文献

Spring5 IOC容器解析——refresh()方法分析_小波同学的技术博客_51CTO博客

https://www.cnblogs.com/dabo-tian/p/16454375.html


http://www.ppmy.cn/news/301909.html

相关文章

云台和华为p30pro_Vlog利器 大疆新微单云台2299元!买!必须买!

01大疆新微单云台2299元&#xff01; 大疆创新通过线上发布的方式正式发布如影Ronin-SC云台(简称如影SC)&#xff0c;单手持微单稳定器如影SC&#xff0c;如影SC专为微单相机打造&#xff0c;轻巧便携的机身集成了强大的产品性能&#xff0c;而如影系列在视频行业中拥有大批的粉…

php擂台赛,「较量」Vlog 视频最强机器擂台赛,究竟哪款最适合你

最近 Vlog 非常流行&#xff0c;今天&#xff0c;我们就来对比一下目前市面上一些主流的 Vlog 设备。我们今天主要来看一看小型便携运动相机&#xff0c;在 Vlog 制作时的表现如何&#xff0c;究竟哪一款最值得大家入手。我们先说下市面上又红又紫的两款产品&#xff0c;大疆 O…

第 1 集:招聘风云!

我原本以为我进了一家创业公司,从此走向摸鱼巅峰。 却不曾想,一个人一干就是一年,第二年,领导看出我想走的架势,仅仅给我新增了一个初级测试! 第三年的某一次迭代,需求的规模彻底倾覆我的抗压能力。 本着不给人就吓吓领导的想法。 我忐忑的走向桌对面:「领导,实在…

JS 校验手机号码

js手机号码的校验 /** 判断字符串是否是手机号码&#xff0c;若是则返回true,若否则返回false **/ function isPhone(phone){ return /^1(3\d|4\d|5\d|6\d|7\d|8\d|9\d)\d{8}$/g.test(phone); }

HTML验证手机号

校验手机号的一些基本点 <script>function demo(){var spanid document.getElementById("spanid")//获取输入框var phid document.getElementById("phid");//获取输入框中的内容var p_value phid.value; //13140008888//定义手机号规则 var re…

正则表达式校验手机号

手机号的正则表达式校验规则如下&#xff1a; validatePhone (rule, value, callback) > {var phonevalue.replace(/\s/g, "");//去除空格//校验手机号&#xff0c;号段主要有(不包括上网卡)&#xff1a;130~139、150~153&#xff0c;155~159&#xff0c;180~18…

MySQL中存放手机号应选择什么数据类型

从表象看&#xff0c;手机号存字符型和数值型没什么区别。若非想要刨根问底的话&#xff0c;可以先了解差别就需要对各个数据类型都有了解才能知道存那种数据类型更合适。 首先手机号一般不做特殊处理&#xff0c;且长度又是固定的&#xff0c;可以选着 char 类型存储。