引言
上篇文章 介绍了 SpringBoot 启动流程,本篇文章继续讲解接下来的流程 —— 容器刷新。
refresh() 方法 容器的刷新由 refreshContext(context)
调用触发,我们看下它的具体实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void refreshContext (ConfigurableApplicationContext context) { refresh(context); if (this .registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { } } } protected void refresh (ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); }
refreshContext()
又调用了 refresh(context)
方法,同时这里也会容器注册关闭勾子(如果存在的话)。refresh
方法则是去调用容器的 refresh()
方法。从前一篇文章中,我们知道容器的实例为 AnnotationConfigServletWebServerApplicationContext
,首先,我们看下它的继承关系图:
AnnotationConfigServletWebServerApplicationContext
继承了父类 ServletWebServerApplicationContext
的 refresh()
方法,我们看下方法实现:
1 2 3 4 5 6 7 8 9 10 @Override public final void refresh () throws BeansException, IllegalStateException { try { super .refresh(); } catch (RuntimeException ex) { stopAndReleaseWebServer(); throw ex; } }
从代码中我们看到,这里会调用其父类的 refresh()
方法,而该方法就是 AbstractApplicationContext
的 refresh()
方法实现(这里我们看到,当发生异常时,则停止并实方 Web 服务):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 @Override public void refresh () throws BeansException, IllegalStateException { synchronized (this .startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } } }
我们很容易看出该方法其实是一个模板方法,其中相关流程都已经添加注释了,接下来我们一一介绍这些步骤。
准备刷新 准备刷新由 repareRefresh()
方法触发,我们看下代码:
1 2 3 4 5 @Override protected void prepareRefresh () { this .scanner.clearCache(); super .prepareRefresh(); }
AnnotationConfigServletWebServerApplicationContext
重写了父类的 prepareRefresh()
方法,其中增加了扫描器的缓存清除操作,之后便是调用父类的 prepareRefresh()
方法,即:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 protected void prepareRefresh () { this .startupDate = System.currentTimeMillis(); this .closed.set(false ); this .active.set(true ); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this ); } else { logger.debug("Refreshing " + getDisplayName()); } } initPropertySources(); getEnvironment().validateRequiredProperties(); if (this .earlyApplicationListeners == null ) { this .earlyApplicationListeners = new LinkedHashSet<>(this .applicationListeners); } else { this .applicationListeners.clear(); this .applicationListeners.addAll(this .earlyApplicationListeners); } this .earlyApplicationEvents = new LinkedHashSet<>(); }
initPropertySources()
是个空方法,AnnotationConfigServletWebServerApplicationContext
则继承了父类 GenericWebApplicationContext
的实现:
1 2 3 4 5 6 7 @Override protected void initPropertySources () { ConfigurableEnvironment env = getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(this .servletContext, null ); } }
这里会从父类获取环境变量对象,如果是 Web 相关的,则调用 StandardServletEnvironment
的 initPropertySources
方法进行初始化,而具体的实现则是由 WebApplicationContextUtils
来完成,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public static void initServletPropertySources (MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { Assert.notNull(sources, "'propertySources' must not be null" ); String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME; if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletContextPropertySource(name, servletContext)); } name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME; if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletConfigPropertySource(name, servletConfig)); } }
以上实现中 servletContext
、servletConfig
参数此时为空,从注释中我们可以看到,该方法是一个幂等方法,也就是该方法可能会被调用多次。这也就解释了,为什么两个关键的参数都为空了。对于接下来的必要属性认证,则是由 StandardEnvironment
的实例完成。我们顺着继承找到最终的方法实现是 AbstractPropertyResolver
类中的 validateRequiredProperties()
方法,以下是它的实现:
1 2 3 4 5 6 7 8 9 10 11 12 @Override public void validateRequiredProperties () { MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); for (String key : this .requiredProperties) { if (this .getProperty(key) == null ) { ex.addMissingRequiredProperty(key); } } if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; } }
大体逻辑是,通过遍历 this.requiredProperties()
集合中的 key,然后获取每个 key 对应的 value,如果不存在,则将当前的 key 存到 MissingRequiredPropertiesException
对象中,如果该对象不为空,则抛出异常。对于这个 Environment 对象则是在 SpringApplication
的 run() 方法中准备 Environment 阶段创建并设置进来的。默认情况下 this.requiredProperties
为空。方法的最后是添加事件监听器到早期应用监听器里(这里应用监听器的来源包括其他监听器回调添加到容器中的)。
获取容器对象 该容器对象就是底层存储 bean 定义的对象,我们看下实现:
1 2 3 4 5 6 7 8 9 10 protected ConfigurableListableBeanFactory obtainFreshBeanFactory () { refreshBeanFactory(); return getBeanFactory(); }
以上两个方法是抽象方法,我们知道该容器的对外对象为 AnnotationConfigServletWebServerApplicationContext
,而该对象又继承了 GenericApplicationContext
,这两个抽象方法也是直接继承了它父类的实现。首先我们先看下 refreshBeanFactory()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 @Override protected final void refreshBeanFactory () throws IllegalStateException { if (!this .refreshed.compareAndSet(false , true )) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once" ); } this .beanFactory.setSerializationId(getId()); }
其实该方法什么也没有做,只是添加了一个防止多次刷新的检测,以及为底层的 bean 容器设置序列化 id。而 getBeanFactory()
方法返回的其实就是我们之前提到过的 DefaultListableBeanFactory
实例。好吧,我们继续往下看!
准备 bean 容器 准备 bean 容器阶段做了很多工作,从以下的代码量就能看出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 protected void prepareBeanFactory (ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this , getEnvironment())); 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); beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this ); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this ); beanFactory.registerResolvableDependency(ApplicationContext.class, this ); beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this )); if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
内容虽然多,不过没关系,我们一点一点分析。我们先看以下代码:
1 2 3 4 5 6 7 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);
首先注册了一个 bean 后置处理器,然后配置 bean 容器来忽略以下多个接口类型。为什么要这么做?我们打开 ApplicationContextAwareProcessor 的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Override @Nullable public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){ return bean; } AccessControlContext acc = null ; if (System.getSecurityManager() != null ) { acc = this .applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null ) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null ; }, acc); } else { invokeAwareInterfaces(bean); } return bean; }
在 postProcessBeforeInitialization
方法中,我们发现第一个 if 语句中就有刚刚我们忽略接口的类型,也就是对这些接口类型做特殊处理,我们来到 invokeAwareInterfaces()
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void invokeAwareInterfaces (Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this .applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this .embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this .applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this .applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this .applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this .applicationContext); } }
从以上代码中我们看到,如果是这些接口的实例,则需要手动设置。看到这里是不是还有点疑惑?没关系,我们继续向下看,以下都是 beanFactory.ignoreDependencyInterface()
方法调用,而入参都是刚刚我们看到的接口类型。那就深入去看看该方法的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 public void ignoreDependencyInterface (Class<?> ifc) { this .ignoredDependencyInterfaces.add(ifc); }
该方法存在于 AbstractAutowireCapableBeanFactory
类中,该类则是用来处理自动注入的 bean 容器。通过方法的注释我们可以了解到,加入到该集合中的类型将会忽略自动注入。我们看下该集合是怎么使用的:
1 2 3 4 5 protected boolean isExcludedFromDependencyCheck (PropertyDescriptor pd) { return (AutowireUtils.isExcludedFromDependencyCheck(pd) || this .ignoredDependencyTypes.contains(pd.getPropertyType()) || AutowireUtils.isSetterDefinedInInterface(pd, this .ignoredDependencyInterfaces)); }
我们把焦点放到 AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces))
方法上,然后看下它的实现:
1 2 3 4 5 6 7 8 9 10 11 12 public static boolean isSetterDefinedInInterface (PropertyDescriptor pd, Set<Class<?>> interfaces) { Method setter = pd.getWriteMethod(); if (setter != null ) { Class<?> targetClass = setter.getDeclaringClass(); for (Class<?> ifc : interfaces) { if (ifc.isAssignableFrom(targetClass) && ClassUtils.hasMethod(ifc, setter)) { return true ; } } } return false ; }
以上代码的意思就是利用反射获取指定类的 setter 方法,然后判断当前类是否是忽略接口的实例,如果是在判断当前类的 setter 方法是否与接口中的 setter 方法一致,如果是返回 true。什么意思?我们举个例子:
1 2 3 4 5 6 7 8 @Component public class MyApplicationContextAware implements ApplicationContextAware { @Autowired void setApplicationContext (ApplicationContext applicationContext) { } }
MyApplicationContextAware 实现了 ApplicationContextAware
接口,重写 setApplicationContext
方法。SpringBoot 支持 setter 注入,所以我们在该方法上添加一个 @Autowired
注解。此时就出现问题了,因为 ApplicationContextAware
执行的阶段发生在自动注入阶段之前,所以根本拿不到 ApplicationContext
对象。但是这些实例在 SpringApplication
启动的时候就有了,所以干脆就让这些接口的实例被自动注入忽略,通过手动的方式设置进来。
1 2 3 4 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this ); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this ); beanFactory.registerResolvableDependency(ApplicationContext.class, this );
为了让 bean 容器也能够注入到我们的程序中,以上需要手动将当前创建好的容器注册到当前 bean 容器里。
1 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this ));
为 bean 容器添加 bean 后置处理器,用于 bean 容器配置期间调用。而 ApplicationListenerDetector
是一个用于检测那些实现了 ApplicationListener
的处理器。
1 2 3 4 5 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
以上添加两个 bean 处理器,一个是 LoadTimeWeaverAwareProcessor
一个是 ContextTypeMatchClassLoader
。前者用于 Spring 提供加载时织入功能,该容器中的任何 bean 都可以实现 LoadTimeWeaverAware 接口,从而接收对加载时织入器实例的引用。后者为一个特殊的类加载器,用于临时匹配类型。
1 2 3 4 5 6 7 8 9 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); }
方法的最后则是向容器中注册环境变量 bean。
容器后置处理器 提供了 postProcessBeanFactory(beanFactory)
方法供子类实现,用于修改配置容器信息,而本例中的容器实现并没有覆盖本方法。
调用容器后置处理器 接下来开始调用容器的后置处理器:
1 2 3 4 5 6 7 8 9 10 protected void invokeBeanFactoryPostProcessors (ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
首先通过 getBeanFactoryPostProcessors()
获取当前容器中的所有容器处理器,然后由 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
方法负责调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 public static void invokeBeanFactoryPostProcessors ( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true , false ); for (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); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); 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(); 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(); } invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true , false ); 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); } } sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); beanFactory.clearMetadataCache(); }
代码量很大,不过逻辑很简单就是按优先级调用 bean 注册处理器以及容器后置处理器。