前言
Spring 核心方法 refresh 刷新流程简要概述及相关源码剖析(一)
继上章分析的继续补充 Refresh 中未分析完的其他方法
registerBeanPostProcessors
在 Spring 中, AbstractApplicationContext#registerBeanPostProcessors 方法被调用时,会把所有匹配的 BPP 实现类进行实例化并且加载到容器中,以便后面进行 Bean 初始化时进行一一调用
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // 找到所有实现了 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. // 记录下 BeanPostProcessor 目标数 // 此处 +1 是因为此方法的后面会添加一个 BeanPostProcessorChecker 类 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; // 添加 BeanPostProcessorChecker(主要用于记录信息)到 beanFactory 中 beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 定义存放实现了 PriorityOrdered 接口 BeanPostProcessor 集合 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); // 定义存放 spring 内部的 BeanPostProcessor List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); // 定义存放实现了 Ordered 接口的 BeanPostProcessor name 集合 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); // 定义存放普通的 BeanPostProcessor name 集合 List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); // 遍历beanFactory中存在的BeanPostProcessor的集合postProcessorNames, for (String ppName : postProcessorNames) { BeanPostProcessor bpp = null; // 如果ppName对应的BeanPostProcessor实例实现了PriorityOrdered接口,则获取到ppName对应的BeanPostProcessor的实例添加到priorityOrderedPostProcessors中 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { bpp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(bpp); } // 如果ppName对应的BeanPostProcessor实例没有实现PriorityOrdered接口,但是实现了Ordered接口,那么将ppName对应的bean实例添加到orderedPostProcessorNames中 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // orderedPostProcessorNames.add(ppName); bpp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(bpp); } else { // 否则将ppName添加到nonOrderedPostProcessorNames中 // nonOrderedPostProcessorNames.add(ppName); bpp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(bpp); } // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中 if (bpp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(bpp); } } // First, register the BeanPostProcessors that implement PriorityOrdered. // 首先,对实现了PriorityOrdered接口的BeanPostProcessor实例进行排序操作 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 注册实现了PriorityOrdered接口的BeanPostProcessor实例添加到beanFactory中 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. // 注册所有实现Ordered的beanPostProcessor // List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); /*for (String ppName : orderedPostProcessorNames) { // 根据ppName找到对应的BeanPostProcessor实例对象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); // 将实现了Ordered接口的BeanPostProcessor添加到orderedPostProcessors集合中 orderedPostProcessors.add(pp); // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中 if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } }*/ // 对实现了Ordered接口的BeanPostProcessor进行排序操作 sortPostProcessors(orderedPostProcessors, beanFactory); // 注册实现了Ordered接口的BeanPostProcessor实例添加到beanFactory中 registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. // 创建存放没有实现PriorityOrdered和Ordered接口的BeanPostProcessor的集合 // List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); // 遍历集合 /*for (String ppName : nonOrderedPostProcessorNames) { // 根据ppName找到对应的BeanPostProcessor实例对象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); // 将没有实现PriorityOrdered和Ordered接口的BeanPostProcessor添加到nonOrderedPostProcessors集合中 nonOrderedPostProcessors.add(pp); // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中 if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } }*/ // 注册没有实现PriorityOrdered和Ordered的BeanPostProcessor实例添加到beanFactory中 registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. // 将所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor进行排序操作 sortPostProcessors(internalPostProcessors, beanFactory); // 注册所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor到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). // 注册ApplicationListenerDetector到beanFactory中 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
对以上方法流程使用图结构和文案进行详细阅览
- beanFactory#getBeanNamesForType(BeanPostProcessor.class:通过 BPP 类型从 beanDefinitionNames 中找到其实现类,返回 String[] 类名数
- 记录 BPP 目标数量,此处 +1 原因是因为在此方法调用的后面添加了一个 BeanPostProcessorChecker 类「该类用于检测完 Bean 以后记录的日志信息」
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
- 创建存储实现 PriorityOrdered 接口、Ordered 接口、两者都未实现的接口【noOrdered】集合,再创建一个实现了 MergedBeanDefinitionPostProcessor 接口类型的内部集合,最后对 BPP 类数组进行遍历,判断其类型是属于哪一种,再加入到对应的集合中.
- 对以上四种集合进行同样的操作,按照顺序进行:PriorityOrdered —>Ordered —> noOrdered —> MergedBeanDefinitionPostProcessor
对集合中元素进行排序
向容器中注册给定的 BPP 类型的 Bean
- 注册 ApplicationListenerDetector 到容器中,该 BPP 在
prepareBeanFactory
中已经注册过了,再次注册只是为了后续可以直接取用
initMessageSource
上下文初始化 message 源,即不同的语言消息体,进行国际化处理,向容器中注入该 bean 实例
protected void initMessageSource() { // 获取bean工厂,一般是 DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 首先判断是否已有xml文件定义了id为messageSource的bean对象 if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { // 如果有,则从BeanFactory中获取这个对象 this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // 当父类bean工厂不为空,并且这个bean对象是HierarchicalMessageSource类型 if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { // 类型强制转换,转换为HierarchicalMessageSource的类型 HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; // 判断父类的messageSource是否为空,如果等于空,则设置父类的messageSource if (hms.getParentMessageSource() == null) { hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { // 如果没有xml文件定义信息源对象,新建DelegatingMessageSource类作为messageSource的bean DelegatingMessageSource dms = new DelegatingMessageSource(); // 给这个DelegatingMessageSource添加父类消息源 dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; // 将这个messageSource实例注册到bean工厂中 beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } }
如果程序中没有进行重定义这个 MessageSource 消息源 Bean,Spring 会默认帮我们注入一个 DelegatingMessageSource 实例
如何实际应用国际化处理
在公司中使用的国际化处理 Bean 一般是 ReloadableResourceBundleMessageSource,它可以帮我们解析 xml、properties 文件,同时可以自定义编码格式
public class LocaleConfig { @Resource private PlatformConfig platformConfig; /** * 加载一下语言资源 **/ @Bean("messageSource") @ConditionalOnMissingBean public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); // 用分号隔开各个语言资源路径 String[] paths = platformConfig.getPath().split(PlatformConstants.COLON); messageSource.setBasenames(paths); messageSource.setDefaultEncoding(platformConfig.getEncoding()); messageSource.setUseCodeAsDefaultMessage(true); messageSource.setFallbackToSystemLocale(false); return messageSource; } /** * 默认解析器 其中locale表示默认语言 */ @Bean public LocaleResolver localeResolver() { return new I18nLocaleResolver(); } /** * 获取请求头国际化信息 */ static class I18nLocaleResolver implements LocaleResolver { @NotNull @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { String languageHeader = httpServletRequest.getHeader(PlatformConstants.LANGUAGE); String languageParameter = httpServletRequest.getParameter(PlatformConstants.LANGUAGE); String language = Objects.nonNull(languageHeader) ? languageHeader : languageParameter; Locale locale = Locale.getDefault(); if (!StringUtils.isEmpty(language)) { String[] split = language.split(PlatformConstants.UNDERSCORE); locale = new Locale(split[0], split[1]); } return locale; } @Override public void setLocale(@NotNull HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } } }
配置消息源核心 Bean 以后,再配置下面的上下文国际化语言 MsgKey 内容处理,前端在 header 中传入当前的国家语言编码,后端在拦截器或者全局异常处理器调用 LocalContext#get
方法返回翻译值
public class LocalContent { private static MessageSource messageSource; public LocalContent(@Qualifier("messageSource") MessageSource messageSource) { LocalContent.messageSource = messageSource; } /** * 获取单个国际化翻译值 */ public static String get(String msgKey) { return messageSource.getMessage(msgKey, null, LocaleContextHolder.getLocale()); } }
initApplicationEventMulticaster
初始化事件监听多路广播器
protected void initApplicationEventMulticaster() { // 获取当前bean工厂,一般是DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 判断容器中是否存在 beanName 为 applicationEventMulticaster 的 bd,也就是说自定义的事件监听多路广播器,必须实现 ApplicationEventMulticaster 接口 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { // 如果有,则从 bean 工厂得到这个 bean 对象 this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { // 如果没有,则默认采用 SimpleApplicationEventMulticaster 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() + "]"); } } }
默认采用的是 SimpleApplicationEventMulticaster 多路广播器类,它的父类 AbstractApplicationEventMulticaster
的内部类专门用一个集合来存储所有的监听器
// 创建监听器助手类,用于存放应用程序的监听器集合,参数是否是预过滤监听器为 false private final ListenerRetriever defaultRetriever = new ListenerRetriever(false); private class ListenerRetriever { // ApplicationListener 对象集合 public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>(); // BeanFactory 中的 applicationListener 类型 Bean 集合 // 在设置监听器时会通过 beanName 去获取监听器,再放入 applicationListeners 集合中 public final Set<String> applicationListenerBeans = new LinkedHashSet<>(); ....... }
onRefresh
该方法留给子类去实现,没有添加任何实现,以 SpringBoot 为例
ServletWebServerApplicationContext
protected void onRefresh() { // 创建主题对象 super.onRefresh(); /* GenericWebApplicationContext protected void onRefresh() { this.themeSource = UiApplicationContextUtils.initThemeSource(this); } */ try { // 开始创建 web 服务->tomcat createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } }
registerListeners
在所有注册的 Bean 中查找监听器,同时将监听器注册到消息广播器中,在这里就涉及到事件的发布以及事件的处理,详细内容可以阅读该文章:Spring 消息源及监听机制
protected void registerListeners() { // 遍历应用程序中存在的监听器集合,并将对应的监听器添加到监听器的多路广播器中 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 从容器中获取所有实现了ApplicationListener接口的bd的bdName // 放入 ApplicationListenerBeans 集合中 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); // 可以直接获取监听器实例进去,无须在取用的时候再次 getBean getApplicationEventMulticaster().addApplicationListener(this.getBean(listenerBeanName,ApplicationListener.class)); } // 此处先发布早期的监听器集合 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (!CollectionUtils.isEmpty(earlyEventsToProcess)) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
finishBeanFactoryInitialization
实例化&初始化 Bean(非懒加载的),如果是实现了 FactoryBean 接口的话,就是懒加载的,只有当某个实例调用它的 getObject 方法才会去加载实现了 FactoryBean 接口的类实例.
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)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 尽早初始化 loadTimeWeaverAware bean,以便尽早注册它们的转换器 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. // 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理 beanFactory.freezeConfiguration(); // 实例化剩下的单例对象 beanFactory.preInstantiateSingletons(); }