别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述Spring源码学习AbstractApplicationContext.refresh()相关的知识,希望能为你提供帮助。
加油加油 ??
大致过程
1@Override 2public void refresh() throws BeansException, IllegalStateException { 3synchronized (this.startupShutdownMonitor) { 4// Prepare this context for refreshing. 5// 准备刷新的上下文环境 6prepareRefresh(); 7 8// Tell the subclass to refresh the internal bean factory. 9//并读取XML,解析注册beanDefination,初始化beanFactory 10// 11ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 12 13// Prepare the bean factory for use in this context. 14//对beanFactory进行功能填充 15prepareBeanFactory(beanFactory); 16 17try { 18// Allows post-processing of the bean factory in context subclasses. 19// 20postProcessBeanFactory(beanFactory); 21 22// Invoke factory processors registered as beans in the context. 23// 激活各种beanFactory的处理器 24invokeBeanFactoryPostProcessors(beanFactory); 25 26// Register bean processors that intercept bean creation. 27// 注册bean创建的Bean处理器(仅注册) 28registerBeanPostProcessors(beanFactory); 29 30// Initialize message source for this context. 31//为上下文初始化message,即不同语言的消息体,国际化处理 32initMessageSource(); 33 34// Initialize event multicaster for this context. 35// 初始化应用消息广播器, 36initApplicationEventMulticaster(); 37 38// Initialize other special beans in specific context subclasses. 39// 留给子类扩展 40onRefresh(); 41 42// Check for listener beans and register them. 43// 在所有注册的bean中查找Listener bean,注册到消息广播器中 44registerListeners(); 45 46// Instantiate all remaining (non-lazy-init) singletons. 47// 初始化剩下的单实例 48finishBeanFactoryInitialization(beanFactory); 49 50// Last step: publish corresponding event. 51// 通知生命周期处理器刷新过程,同时发出ContextRefreshedEvent 52finishRefresh(); 53} 54 55catch (BeansException ex) { 56if (logger.isWarnEnabled()) { 57logger.warn("Exception encountered during context initialization - " + 58"cancelling refresh attempt: " + ex); 59} 60 61// Destroy already created singletons to avoid dangling resources. 62destroyBeans(); 63 64// Reset ‘active‘ flag. 65cancelRefresh(ex); 66 67// Propagate exception to caller. 68throw ex; 69} 70 71finally { 72// Reset common introspection caches in Spring‘s core, since we 73// might not ever need metadata for singleton beans anymore... 74resetCommonCaches(); 75} 76} 77}
(一)环境准备
1protected void prepareRefresh() { 2// Switch to active. 3this.startupDate = System.currentTimeMillis(); 4this.closed.set(false); 5this.active.set(true); 6 7if (logger.isDebugEnabled()) { 8if (logger.isTraceEnabled()) { 9logger.trace("Refreshing " + this); 10} 11else { 12logger.debug("Refreshing " + getDisplayName()); 13} 14} 15 16// Initialize any placeholder property sources in the context environment. 17// 空方法 留给子类扩展使用 18// 继承ClassPathXmlApplicationContext重写initPropertySources()方法即可添加定制化验证 19initPropertySources(); 20 21// Validate that all properties marked as required are resolvable: 22// see ConfigurablePropertyResolver#setRequiredProperties 23//检验属性的合法 24getEnvironment().validateRequiredProperties(); 25 26// Store pre-refresh ApplicationListeners... 27if (this.earlyApplicationListeners == null) { 28this.earlyApplicationListeners = new LinkedHashSet< > (this.applicationListeners); 29} 30else { 31// Reset local application listeners to pre-refresh state. 32this.applicationListeners.clear(); 33this.applicationListeners.addAll(this.earlyApplicationListeners); 34} 35 36// Allow for the collection of early ApplicationEvents, 37// to be published once the multicaster is available... 38this.earlyApplicationEvents = new LinkedHashSet< > (); 39}
(1)留给子类扩展接口
(2)验证属性合法性
(3)记录容器中的早期事件
(二)加载beanFactory
1protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { 2refreshBeanFactory(); 3return getBeanFactory(); 4}
1@Override 2protected final void refreshBeanFactory() throws BeansException { 3if (hasBeanFactory()) { 4destroyBeans(); 5closeBeanFactory(); 6} 7try { 8//(1)为上下文创建DefaultListableBeanFactory,并设置序列化id 9DefaultListableBeanFactory beanFactory = createBeanFactory(); 10beanFactory.setSerializationId(getId()); 11//(2)customizeBeanFactory()配置覆盖方法,循环依赖,子类可覆盖,是一个扩展接口,同样继承ClassPathXmlApplicationContext重写此方法即可 12customizeBeanFactory(beanFactory); // 配置覆盖方法,循环依赖,子类可覆盖 13loadBeanDefinitions(beanFactory); // (1)创建XmlBeanDefinitionReader,(2)initBeanDefinitionReader()可扩展接口(3)loadBeanDefinitions:解析xml为beanDefinition 14synchronized (this.beanFactoryMonitor) { 15this.beanFactory = beanFactory; 16} 17} 18catch (IOException ex) { 19throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); 20} 21}
最重要的就是解析beanDefinition,注册到beanDefinitionMap中
(3)prepareBeanFactory()功能扩展
1protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 2// Tell the internal bean factory to use the context‘s class loader etc. 3beanFactory.setBeanClassLoader(getClassLoader()); 4// TODO SpEl处理器如何使用 5beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); 6// TODO 属性注册编辑器 7beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); 8 9// Configure the bean factory with context callbacks. 10// 增加内置类 11beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 12// 设置忽略自动装配的接口 13beanFactory.ignoreDependencyInterface(EnvironmentAware.class); 14beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); 15beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); 16beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); 17beanFactory.ignoreDependencyInterface(MessageSourceAware.class); 18beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); 19 20// BeanFactory interface not registered as resolvable type in a plain factory. 21// MessageSource registered (and found for autowiring) as a bean. 22// 设置自动装配的特殊规则 23beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); 24beanFactory.registerResolvableDependency(ResourceLoader.class, this); 25beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); 26beanFactory.registerResolvableDependency(ApplicationContext.class, this); 27 28// Register early post-processor for detecting inner beans as ApplicationListeners. 29beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); 30 31// Detect a LoadTimeWeaver and prepare for weaving, if found. 32// 增加对AspectJ的支持 33if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 34beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 35// Set a temporary ClassLoader for type matching. 36beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 37} 38 39// Register default environment beans. 40if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { 41beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); 42} 43if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { 44beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); 45} 46if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { 47beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); 48} 49}
(四)postProcessBeanFactory()是一个可扩展接口
(五)invokeBeanFactoryPostProcessors
1protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { 2PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 3 4// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime 5// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) 6if (beanFactory.getTempClassLoader() == null & & beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 7beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 8beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 9} 10}
1public static void invokeBeanFactoryPostProcessors( 2ConfigurableListableBeanFactory beanFactory, List< BeanFactoryPostProcessor> beanFactoryPostProcessors) { 3 4// Invoke BeanDefinitionRegistryPostProcessors first, if any. 5Set< String> processedBeans = new HashSet< > (); 6 7if (beanFactory instanceof BeanDefinitionRegistry) { 8BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 9List< BeanFactoryPostProcessor> regularPostProcessors = new ArrayList< > (); 10List< BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList< > (); 11 12// (1)beanFactory是BeanDefinitionRegistry类型,postProcessor是BeanDefinitionRegistryPostProcessor类型 13//postProcessor转化为BeanDefinitionRegistryPostProcessor类型添加进 registryProcessors 14// (2)beanFactory是BeanDefinitionRegistry类型,但postProcessor不是BeanDefinitionRegistryPostProcessor类型 15//postProcessor添加进 regularPostProcessors 16for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { 17if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { 18BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; 19//TODO 调用了? 20registryProcessor.postProcessBeanDefinitionRegistry(registry); 21 22registryProcessors.add(registryProcessor); 23} else { 24regularPostProcessors.add(postProcessor); 25} 26} 27 28// Do not initialize FactoryBeans here: We need to leave all regular beans 29// uninitialized to let the bean factory post-processors apply to them! 30// Separate between BeanDefinitionRegistryPostProcessors that implement 31// PriorityOrdered, Ordered, and the rest. 32List< BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList< > (); 33 34// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. 35// BeanDefinitionRegistryPostProcessors+PriorityOrdered→ invokeBeanDefinitionRegistryPostProcessors() 36String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 37for (String ppName : postProcessorNames) { 38if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 39currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 40processedBeans.add(ppName); 41} 42} 43sortPostProcessors(currentRegistryProcessors, beanFactory); 44registryProcessors.addAll(currentRegistryProcessors); 45invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 46currentRegistryProcessors.clear(); 47 48// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. 49// BeanDefinitionRegistryPostProcessors+Ordered→ invokeBeanDefinitionRegistryPostProcessors() 50postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 51for (String ppName : postProcessorNames) { 52if (!processedBeans.contains(ppName) & & beanFactory.isTypeMatch(ppName, Ordered.class)) { 53currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 54processedBeans.add(ppName); 55} 56} 57sortPostProcessors(currentRegistryProcessors, beanFactory); 58registryProcessors.addAll(currentRegistryProcessors); 59invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 60currentRegistryProcessors.clear(); 61 62// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. 63// BeanDefinitionRegistryPostProcessors→ invokeBeanDefinitionRegistryPostProcessors() 64boolean reiterate = true; 65while (reiterate) { 66reiterate = false; 67postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 68for (String ppName : postProcessorNames) { 69// 避免重复加载 70if (!processedBeans.contains(ppName)) { 71currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 72processedBeans.add(ppName); 73reiterate = true; 74} 75} 76sortPostProcessors(currentRegistryProcessors, beanFactory); 77registryProcessors.addAll(currentRegistryProcessors); 78invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 79currentRegistryProcessors.clear(); 80} 81 82// Now, invoke the postProcessBeanFactory callback of all processors handled so far. 83//BeanDefinitionRegistryPostProcessor 84invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); 85//BeanFactoryPostProcessor 86invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); 87} else { 88// Invoke factory processors registered with the context instance. 89invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); 90} 91 92// Do not initialize FactoryBeans here: We need to leave all regular beans 93// uninitialized to let the bean factory post-processors apply to them! 94String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); 95 96// Separate between BeanFactoryPostProcessors that implement PriorityOrdered, 97// Ordered, and the rest. 98List< BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList< > (); 99List< String> orderedPostProcessorNames = new ArrayList< > (); 100List< String> nonOrderedPostProcessorNames = new ArrayList< > (); 101for (String ppName : postProcessorNames) { 102if (processedBeans.contains(ppName)) { 103// 避免重复加载 104// skip - already processed in first phase above 105} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 106priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); 107} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 108orderedPostProcessorNames.add(ppName); 109} else { 110nonOrderedPostProcessorNames.add(ppName); 111} 112} 113 114// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. 115// BeanFactoryPostProcessor+PriorityOrdered→ invokeBeanFactoryPostProcessors() 116sortPostProcessors(priorityOrderedPostProcessors, beanFactory); 117invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); 118 119// Next, invoke the BeanFactoryPostProcessors that implement Ordered. 120//BeanFactoryPostProcessor+Ordered→ invokeBeanFactoryPostProcessors() 121List< BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList< > (); 122for (String postProcessorName : orderedPostProcessorNames) { 123orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 124} 125sortPostProcessors(orderedPostProcessors, beanFactory); 126invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); 127 128// Finally, invoke all other BeanFactoryPostProcessors. 129//BeanFactoryPostProcessors→ invokeBeanFactoryPostProcessors() 130List< BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList< > (); 131for (String postProcessorName : nonOrderedPostProcessorNames) { 132nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 133} 134invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); 135 136// Clear cached merged bean definitions since the post-processors might have 137// modified the original metadata, e.g. replacing placeholders in values... 138beanFactory.clearMetadataCache(); 139}
(1)了解BeanDefinitionRegistryPostProcessor 实现了 BeanFactoryPostProcessor
1 public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { 2 3void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
(2)了解BeanFactoryPostProcessor
1 public interface BeanFactoryPostProcessor { 2 3void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; 4 5 }
(3)了解PriorityOrdered实现Ordered
1 public interface PriorityOrdered extends Ordered { 2 }
(4)了解Ordered
1 public interface Ordered { 2 3/** 4* Useful constant for the highest precedence value. 5* @see java.lang.Integer#MIN_VALUE 6*/ 7int HIGHEST_PRECEDENCE = Integer.MIN_VALUE; 8 9/** 10* Useful constant for the lowest precedence value. 11* @see java.lang.Integer#MAX_VALUE 12*/ 13int LOWEST_PRECEDENCE = Integer.MAX_VALUE; 14 15 16int getOrder(); 17 18 }
加载优先级:
(a)BeanDefinitionRegistryPostProcessor优先于BeanFactoryPostProcessor
(b)PriorityOrdered优先于Ordered,其中order值越小越先加载
(六)注册BeanPostProcessor
1protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { 2PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); 3}
1 public static void registerBeanPostProcessors( 2ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { 3 4String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); 5 6// Register BeanPostProcessorChecker that logs an info message when 7// a bean is created during BeanPostProcessor instantiation, i.e. when 8// a bean is not eligible for getting processed by all BeanPostProcessors. 9//当后置处理器还没有注册就已经开始bean初始化时打印出BeanPostProcessorChecker的信息 10int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; 11beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); 12 13// Separate between BeanPostProcessors that implement PriorityOrdered, 14// Ordered, and the rest. 15//根据是否继承PriorityOrdered,Ordered, and the rest分类 16List< BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList< > (); 17List< BeanPostProcessor> internalPostProcessors = new ArrayList< > (); 18List< String> orderedPostProcessorNames = new ArrayList< > (); 19List< String> nonOrderedPostProcessorNames = new ArrayList< > (); 20for (String ppName : postProcessorNames) { 21if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 22BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); 23priorityOrderedPostProcessors.add(pp); 24if (pp instanceof MergedBeanDefinitionPostProcessor) { 25internalPostProcessors.add(pp); 26} 27} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 28orderedPostProcessorNames.add(ppName); 29} else { 30nonOrderedPostProcessorNames.add(ppName); 31} 32} 33 34// First, register the BeanPostProcessors that implement PriorityOrdered. 35sortPostProcessors(priorityOrderedPostProcessors, beanFactory); 36// 注册实现PriorityOrdered.的 37registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); 38 39// Next, register the BeanPostProcessors that implement Ordered. 40List< BeanPostProcessor> orderedPostProcessors = new ArrayList< > (); 41for (String ppName : orderedPostProcessorNames) { 42BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); 43orderedPostProcessors.add(pp); 44if (pp instanceof MergedBeanDefinitionPostProcessor) { 45internalPostProcessors.add(pp); 46} 47} 48//排序 49sortPostProcessors(orderedPostProcessors, beanFactory); 50//注册实现 Ordered 的 51registerBeanPostProcessors(beanFactory, orderedPostProcessors); 52 53// Now, register all regular BeanPostProcessors. 54List< BeanPostProcessor> nonOrderedPostProcessors = new ArrayList< > (); 55for (String ppName : nonOrderedPostProcessorNames) { 56BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); 57nonOrderedPostProcessors.add(pp); 58if (pp instanceof MergedBeanDefinitionPostProcessor) { 59internalPostProcessors.add(pp); 60} 61} 62// 注册实现没有实现PriorityOrderedOrdered和的 63registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); 64 65// Finally, re-register all internal BeanPostProcessors. 66sortPostProcessors(internalPostProcessors, beanFactory); 67// 注册所有MergedBeanDefinitionPostProcessor类型的PostProcessors 68registerBeanPostProcessors(beanFactory, internalPostProcessors); 69 70// Re-register post-processor for detecting inner beans as ApplicationListeners, 71// moving it to the end of the processor chain (for picking up proxies etc). 72// 注册ApplicationListenerDetector 73beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); 74}
【Spring源码学习AbstractApplicationContext.refresh()】
1@Override 2public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { 3Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); 4// Remove from old position, if any 5this.beanPostProcessors.remove(beanPostProcessor); 6// Track whether it is instantiation/destruction aware 7if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { 8this.hasInstantiationAwareBeanPostProcessors = true; 9} 10if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { 11this.hasDestructionAwareBeanPostProcessors = true; 12} 13// 先删后增 保证是唯一最新 14// Add to end of list 15this.beanPostProcessors.add(beanPostProcessor); 16}
(1) 顺序:BeanPostProcessorChecker> PriorityOrdered> Ordered> 无序> MergedBeanDefinitionPostProcessor类型> ApplicationListenerDetector
(2) addBeanPostProcessor 先删后增 保证是唯一最新
(七) 初始化消息资源
1protected void initMessageSource() { 2ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 3// bean id = messageSource 4if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { 5this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); 6// Make MessageSource aware of parent MessageSource. 7if (this.parent != null & & this.messageSource instanceof HierarchicalMessageSource) { 8HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; 9if (hms.getParentMessageSource() == null) { 10// Only set parent context as parent MessageSource if no parent MessageSource 11// registered already. 12hms.setParentMessageSource(getInternalParentMessageSource()); 13} 14} 15if (logger.isTraceEnabled()) { 16logger.trace("Using MessageSource [" + this.messageSource + "]"); 17} 18} 19else { 20// Use empty MessageSource to be able to accept getMessage calls. 21DelegatingMessageSource dms = new DelegatingMessageSource(); 22dms.setParentMessageSource(getInternalParentMessageSource()); 23this.messageSource = dms; 24beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); 25if (logger.isTraceEnabled()) { 26logger.trace("No ‘" + MESSAGE_SOURCE_BEAN_NAME + "‘ bean, using [" + this.messageSource + "]"); 27} 28} 29}
加油??
推荐阅读
- Dapper系列作者(懒懒的程序员一枚)
- appium微信小程序
- uniapp - textarea层级过高影响到遮罩层
- .net core读取appsettings.config中文乱码问题
- 和大家交流一下微信IPAD安卓协议源码
- 创建并运行rn app项目
- MyBatis Mapper文件简述
- App crash原因以及解决办法
- uniapp - cell组件