- 一、背景
- 1.1、run方法整体流程
- 1.2、刷新的整体调用流程
- 1.3、本文解读范围
- 二、准备刷新
- 2.1、准备刷新的流程
- 2.2、初始化上下文环境中servlet相关属性源
- 2.3、校验require属性
- 2.4、预刷新应用程序监听器
- 三、通知子类刷新内部beanFactory
- 四、准备beanFactory
- 4.1、准备beanFactory的整体流程
- 4.2、StandardBeanexpressionResolver
- 4.3、其他简单说明
- 五、上下文中子类对bean工厂进行后处理
- 结语
上一篇我们解读了准备应用上下文,本篇主要解读刷新应用上下文(上),老样子还是回顾下启动的整体流程,这样就能不迷路。
1.1、run方法整体流程接下来的几个方法所在类的具体路径:org.springframework.boot.SpringApplication
public static ConfigurableApplicationContext run(Class> primarySource, String... args) { return run(new Class>[] { primarySource }, args); } public static ConfigurableApplicationContext run(Class>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); } public ConfigurableApplicationContext run(String... args) { // 1、创建并启动计时监控类 StopWatch stopWatch = new StopWatch(); stopWatch.start(); // 2、初始化启动上下文、初始化应用上下文 DefaultBootstrapContext bootstrapContext = createBootstrapContext(); ConfigurableApplicationContext context = null; // 3、设置无头属性:“java.awt.headless”,默认值为:true(没有图形化界面) configureHeadlessProperty(); // 4、创建所有 Spring 运行监听器并发布应用启动事件 SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(bootstrapContext, this.mainApplicationClass); try { // 5、初始化默认应用参数类 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 6、根据运行监听器和应用参数来准备 Spring 环境 ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); configureIgnoreBeanInfo(environment); // 7、创建 Banner 并打印 Banner printedBanner = printBanner(environment); // 8、创建应用上下文 context = createApplicationContext(); context.setApplicationStartup(this.applicationStartup); // 9、准备应用上下文 prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner); // 10、刷新应用上下文 refreshContext(context); // 11、应用上下文刷新后置处理 afterRefresh(context, applicationArguments); // 12、停止计时监控类 stopWatch.stop(); // 13、输出日志记录执行主类名、时间信息 if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } // 14、发布应用上下文启动完成事件 listeners.started(context); // 15、执行所有 Runner 运行器 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, listeners); throw new IllegalStateException(ex); } try { // 16、发布应用上下文就绪事件 listeners.running(context); } catch (Throwable ex) { // 17、错误处理 handleRunFailure(context, ex, null); throw new IllegalStateException(ex); } // 18、返回应用上下文 return context; }1.2、刷新的整体调用流程
此方法所在类的具体路径:org.springframework.boot.SpringApplication
private void refreshContext(ConfigurableApplicationContext context) { if (this.registerShutdownHook) { // 又增加一个监听器ApplicationContextClosedListener,上一文我们讲过准备刷新是11个,现在就是12个了 shutdownHook.registerApplicationContext(context); } refresh(context); } protected void refresh(ConfigurableApplicationContext applicationContext) { // 最终实现是AbstractApplicationContext的refresh方法 applicationContext.refresh(); }
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
@Override public void refresh() throws BeansException, IllegalStateException { // 同步的方式刷新 synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // 准备此上下文以进行刷新 prepareRefresh(); // 告诉子类刷新内部bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 准备bean工厂,以便在此上下文中使用 prepareBeanFactory(beanFactory); try { // 允许在上下文中子类对bean工厂进行后处理 postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // 调用在上下文中注册为bean的工厂处理器 invokeBeanFactoryPostProcessors(beanFactory); // 注册拦截bean创建的BeanPostProcessor registerBeanPostProcessors(beanFactory); beanPostProcess.end(); // 为此上下文初始化消息源,也就是注册DelegatingMessageSource initMessageSource(); // 为此上下文初始化事件multicaster initApplicationEventMulticaster(); // 初始化特定上下文子类中的其他特殊bean,比如创建内置的Servlet容器 onRefresh(); // 检查监听器bean并注册它们 registerListeners(); // 实例化所有剩余的(非惰性初始化)单例 finishBeanFactoryInitialization(beanFactory); // 最后一步:发布相应的事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁已创建的单例以避免悬空资源 destroyBeans(); // 重置“active”标志 cancelRefresh(ex); // 将异常传播到调用方 throw ex; } finally { //重置Spring核心中的常见内省缓存,因为我们可能不再需要单例bean的元数据了。。。 resetCommonCaches(); contextRefresh.end(); } } }
- 同步 *** 作
- 准备此上下文以进行刷新
- 告诉子类刷新内部bean工厂
- 准备bean工厂,以便在此上下文中使用
- 允许在上下文中子类对bean工厂进行后处理
- 调用在上下文中注册为bean的工厂处理器
- 注册拦截bean创建的BeanPostProcessor
- 为此上下文初始化消息源,也就是注册DelegatingMessageSource
- 为此上下文初始化事件Multicaster
- 初始化特定上下文子类中的其他特殊bean
- 检查监听器bean并注册它们
- 实例化所有剩余的(非惰性初始化)单例
- 发布相应的事件
本文主要讲解refresh()方法的部分内容,也就是:
// 准备此上下文以进行刷新 prepareRefresh(); // 告诉子类刷新内部bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 准备bean工厂,以便在此上下文中使用 prepareBeanFactory(beanFactory); try { // 允许在上下文中子类对bean工厂进行后处理 postProcessBeanFactory(beanFactory); // 后面省略,本到此处 } catch (BeansException ex) { }finally{ }
整个方法的内容比较多,为了比较详细的解读,我们就分多个部分解读,本文就解读到上下文中子类对bean工厂进行后处理。
二、准备刷新 2.1、准备刷新的流程此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
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()); } } // 初始化上下文环境中servlet相关属性源 // 通过调用子类GenericWebApplicationContext重写后的方法来实现 initPropertySources(); //验证标记为“required”的所有属性是否可解析: //具体可以参阅ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // 存储预刷新应用程序监听器 if (this.earlyApplicationListeners == null) { // 此时上下文里是12个监听器,具体可有看我上一篇文章里11个的来源及本文中的添加的1个 this.earlyApplicationListeners = new linkedHashSet<>(this.applicationListeners); } else { // 将本地应用程序监听器重置为预刷新状态 this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // 一旦multicaster 可用,允许早期的ApplicationEvents进行发布 this.earlyApplicationEvents = new linkedHashSet<>(); }
- 将上下文切换到激活状态
- 通过调用子类GenericWebApplicationContext重写后的方法来初始化上下文环境中servlet相关属性源
- 预刷新应用程序监听器处理
- 定义早期ApplicationEvent事件
此方法所在类的具体路径:org.springframework.web.context.support.GenericWebApplicationContext
public class GenericWebApplicationContext extends GenericApplicationContext implements ConfigurableWebApplicationContext, ThemeSource { @Override protected void initPropertySources() { // 获取环境为ApplicationServletEnvironment ConfigurableEnvironment env = getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { // ApplicationServletEnvironment 继承了StandardServletEnvironment // StandardServletEnvironment 实现了ConfigurableWebEnvironment ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null); } } }
此方法所在类的具体路径:org.springframework.web.context.support.StandardServletEnvironment
public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment { @Override public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { // getPropertySources()的值具体可以参考我之前的文章:启动流程分析之应用环境准备 WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig); } }
大致如下结构:
ApplicationServletEnvironment { activeProfiles=[], defaultProfiles=[default], propertySources=[ ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, SimpleCommandLinePropertySource {name='commandLineArgs'}, StubPropertySource {name='servletConfigInitParams'}, StubPropertySource {name='servletContextInitParams'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource@1483145520 {name='systemEnvironment'}, RandomValuePropertySource@1961129028 {name='random'}, OriginTrackedMapPropertySource@1506938939 {name='Config resource ' } ] }
public abstract class WebApplicationContextUtils { public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { Assert.notNull(sources, "'propertySources' must not be null"); // servletContextInitParams String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME; if (servletContext != null && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletContextPropertySource(name, servletContext)); } // servletConfigInitParams name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME; if (servletConfig != null && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletConfigPropertySource(name, servletConfig)); } } }
servletContext为null故什么都没有做
2.3、校验require属性public abstract class AbstractEnvironment implements ConfigurableEnvironment { private final ConfigurablePropertyResolver propertyResolver; @Override public void validateRequiredProperties() throws MissingRequiredPropertiesException { // 这里的propertyResolver为PropertySourcesPropertyResolver,这个值是在prepareEnvironment方法创建环境时初始化赋值的 this.propertyResolver.validateRequiredProperties(); } }
这里的propertyResolver为PropertySourcesPropertyResolver,这个值是在prepareEnvironment方法创建环境时初始化赋值的,PropertySourcesPropertyResolver 继承抽象类 AbstractPropertyResolver
public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {}
AbstractPropertyResolver又实现了接口ConfigurablePropertyResolver
public abstract class AbstractPropertyResolver implements ConfigurablePropertyResolver { private final Set2.4、预刷新应用程序监听器requiredProperties = new linkedHashSet<>(); @Override public void validateRequiredProperties() { MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); // requiredProperties是空的 for (String key : this.requiredProperties) { if (this.getProperty(key) == null) { ex.addMissingRequiredProperty(key); } } if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; } } }
此时的预刷新应用程序监听器applicationListeners(12个):
- RSocketPortInfoApplicationContextInitializer的内部类Listener
- ServerPortInfoApplicationContextInitializer
- ConditionevaluationReportLoggingListener的内部类ConditionevaluationReportListener
- EnvironmentPostProcessorApplicationListener
- AnsiOutputApplicationListener
- LoggingApplicationListener
- BackgroundPreinitializer
- DelegatingApplicationListener
- ParentContextCloserApplicationListener
- ClearCachesApplicationListener
- FileEncodingApplicationListener
- SpringApplicationShutdownHook的内部类ApplicationContextClosedListener
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); // 返回的beanFactory为DefaultListableBeanFactory,具体可以查看我之前的文章:启动流程分析之创建应用上下文 return getBeanFactory(); } }
- 刷新beanFactory
- 获取beanFactory,此处得到的是DefaultListableBeanFactory
我们看下refreshBeanFactory(),此方法所在类的具体路径:org.springframework.web.context.support.GenericWebApplicationContext
public class GenericWebApplicationContext extends GenericApplicationContext implements ConfigurableWebApplicationContext, ThemeSource { @Override protected final void refreshBeanFactory() throws IllegalStateException { // 这里的refreshed是一个刷新标志,未刷新就设置为true if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } // 获取的上下文id为application // 设置beanFactory的序列化id this.beanFactory.setSerializationId(getId()); } }
此方法所在类的具体路径:org.springframework.beans.factory.support.DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { // 序列化工厂映射:key为序列化id,value为弱引用对象 private static final Map四、准备beanFactory 4.1、准备beanFactory的整体流程> serializableFactories = new ConcurrentHashMap<>(8); // 此工厂的可序列化Id,用于序列化 @Nullable private String serializationId; public void setSerializationId(@Nullable String serializationId) { if (serializationId != null) { // 序列化id不为空时,把DefaultListableBeanFactory通过弱引用加入映射 serializableFactories.put(serializationId, new WeakReference<>(this)); } else if (this.serializationId != null) { serializableFactories.remove(this.serializationId); } // 设置应用上下文序列化id(唯一) this.serializationId = serializationId; } }
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore"); protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 告诉内部bean工厂使用上下文的类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 如果没有配置属性spring.spel.ignore,则默认为false,也就是支持spel if (!shouldIgnoreSpel) { // 实例化一个标准Bean表达式解析器StandardBeanexpressionResolver beanFactory.setBeanexpressionResolver(new StandardBeanexpressionResolver(beanFactory.getBeanClassLoader())); } // 添加属性注册编辑器,ResourceEditorRegistrar的registerCustomEditors方法主要是注册简单通用常用类型的属性编辑器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加后置处理器,使用上下文回调配置beanFactory beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 添加依赖项检查和autowire时要忽略的依赖项接口。默认情况下,仅忽略BeanFactory接口 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.ignoreDependencyInterface(ApplicationStartupAware.class); // BeanFactory接口未在普通工厂中注册为可解析类型 // MessageSource作为bean注册(并找到自动连接) beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 注册早期的后置处理器用于检测内部bean,像ApplicationListener beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 检测LoadTimeWeaver并准备编织(如果发现) if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // 为了类型匹配设置临时类加载器 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 注册默认环境bean // 如果beanFactory里不存在beanName为environment的bean,则注册environment if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 如果beanFactory里不存在beanName为systemProperties的bean,则注册systemProperties if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 如果beanFactory里不存在beanName为systemEnvironment的bean,则注册systemEnvironment if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } // 如果beanFactory里不存在beanName为applicationStartup的bean,则注册applicationStartup if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) { beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup()); } } }
- 告诉内部bean工厂使用上下文的类加载器
- 实例化一个标准Bean表达式解析器StandardBeanexpressionResolver
- 添加后置处理器,使用上下文回调配置beanFactory
- 添加属性注册编辑器ResourceEditorRegistrar
- 添加依赖项检查和autowire时要忽略的依赖项接口
- 注册早期的后置处理器用于检测内部bean
- 检测LoadTimeWeaver并准备编织
- 注册默认环境bean(environment、systemProperties、systemEnvironment、applicationStartup)
此方法所在类的具体路径:org.springframework.context.expression.StandardBeanexpressionResolver
public class StandardBeanexpressionResolver implements BeanexpressionResolver { // 默认表达式前缀: "#{" public static final String DEFAULT_expression_PREFIX = "#{"; // 默认表达式后缀: "}" public static final String DEFAULT_expression_SUFFIX = "}"; private String expressionPrefix = DEFAULT_expression_PREFIX; private String expressionSuffix = DEFAULT_expression_SUFFIX; public StandardBeanexpressionResolver(@Nullable ClassLoader beanClassLoader) { this.expressionParser = new SpelexpressionParser(new SpelParserConfiguration(null, beanClassLoader)); } }
构造方法就是获取了一个表达式解析器SpelexpressionParser,而SpelexpressionParser的构造方法(主要参数是SpelParserConfiguration)主要是初始化了Spel编译模式,该模式主要由三种:
- SpelCompilerMode.OFF
- SpelCompilerMode.IMMEDIATE
- SpelCompilerMode.IMMEDIATE
本文这里是默认的SpelCompilerMode.OFF,关于SpelParserConfiguration的构造方法比较简单,大家可以自行查阅。
4.3、其他简单说明1、ResourceEditorRegistrar 的registerCustomEditors方法主要是注册简单通用常用类型的属性编辑器
2、ApplicationListenerDetector:主要作用:
- 在Bean初始化完成之后:如果bean是 ApplicationListener的实例,并且Bean是单例,就会加入到this.applicationListeners中
- 在Bean销毁之前搞事情:如果Bean是一个ApplicationListener的实例,则会从事件广播器ApplicationEventMulticaster中删除
3、ApplicationContextAwareProcessor 可用来处理实现ApplicationContextAware的bean对象,它的postProcessBeforeInitialization方法是要忽略的依赖项接口(具体见第4点),则注入Aware接口,否则直接返回bean
4、要忽略的依赖项接口(创建应用上下文时添加了三个):
- org.springframework.context.ApplicationEventPublisherAware(本次添加)
- org.springframework.context.MessageSourceAware(本次添加)
- org.springframework.beans.factory.BeanFactoryAware
- org.springframework.context.EnvironmentAware(本次添加)
- org.springframework.context.ResourceLoaderAware(本次添加)
- org.springframework.context.EmbeddedValueResolverAware(本次添加)
- org.springframework.context.ApplicationContextAware(本次添加)
- org.springframework.context.ApplicationStartupAware(本次添加)
- org.springframework.beans.factory.BeanNameAware
- org.springframework.beans.factory.BeanClassLoaderAware
5、在普通工厂中不是可解析型的beanFactory接口
- org.springframework.context.ApplicationContext
- org.springframework.beans.factory.BeanFactory
- org.springframework.core.io.ResourceLoader
- org.springframework.context.ApplicationEventPublisher
此方法所在类的具体路径:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry { protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } } }
这里调用父类ServletWebServerApplicationContext的postProcessBeanFactory方法。
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext { @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 添加后置处理器(添加完就3个了) beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this)); // 添加要忽略的依赖项接口() beanFactory.ignoreDependencyInterface(ServletContextAware.class); // 注册web应用程序作用域 registerWebApplicationScopes(); } }
- 添加后置处理器
- 添加要忽略的依赖项接口
- 注册web应用程序作用域
public class WebApplicationContextServletContextAwareProcessor extends ServletContextAwareProcessor { private final ConfigurableWebApplicationContext webApplicationContext; public WebApplicationContextServletContextAwareProcessor(ConfigurableWebApplicationContext webApplicationContext) { Assert.notNull(webApplicationContext, "WebApplicationContext must not be null"); this.webApplicationContext = webApplicationContext; } }
后置处理器:
- ApplicationContextAwareProcessor(prepareBeanFactory方法里添加)
- ApplicationListenerDetector(prepareBeanFactory方法里添加)
- WebApplicationContextServletContextAwareProcessor(本次添加)
要忽略的依赖项接口:
- org.springframework.context.ApplicationEventPublisherAware
- org.springframework.context.MessageSourceAware
- org.springframework.web.context.ServletContextAware(本次添加)
- org.springframework.beans.factory.BeanFactoryAware
- org.springframework.context.EnvironmentAware
- org.springframework.context.ResourceLoaderAware
- org.springframework.context.EmbeddedValueResolverAware
- org.springframework.context.ApplicationContextAware
- org.springframework.context.ApplicationStartupAware
- org.springframework.beans.factory.BeanNameAware
- org.springframework.beans.factory.BeanClassLoaderAware
关于ExistingWebApplicationScopes的实例化:
private void registerWebApplicationScopes() { ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(getBeanFactory()); WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory()); existingScopes.restore(); } public static class ExistingWebApplicationScopes { private static final SetSCOPES; static { Set scopes = new linkedHashSet<>(); scopes.add(WebApplicationContext.SCOPE_REQUEST); scopes.add(WebApplicationContext.SCOPE_SESSION); SCOPES = Collections.unmodifiableSet(scopes); } private final ConfigurableListableBeanFactory beanFactory; private final Map scopes = new HashMap<>(); public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) { this.beanFactory = beanFactory; for (String scopeName : SCOPES) { Scope scope = beanFactory.getRegisteredScope(scopeName); if (scope != null) { this.scopes.put(scopeName, scope); } } } }
关于registerWebApplicationScopes方法:
public abstract class WebApplicationContextUtils { public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) { registerWebApplicationScopes(beanFactory, null); } public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) { // 注册request作用域 beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope()); // 注册session作用域 beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope()); if (sc != null) { ServletContextScope appScope = new ServletContextScope(sc); beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // Register as ServletContext attribute, for ContextCleanupListener to detect it. sc.setAttribute(ServletContextScope.class.getName(), appScope); } // 添加普通工厂中不是可解析型的beanFactory接口 beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory()); beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory()); beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory()); beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory()); if (jsfPresent) { FacesDependencyRegistrar.registerFacesDependencies(beanFactory); } } }
在普通工厂中不是可解析型的beanFactory接口(文章之前加入了4个):
- javax.servlet.ServletResponse(本次添加)
- org.springframework.context.ApplicationContext
- org.springframework.web.context.request.WebRequest(本次添加)
- org.springframework.beans.factory.BeanFactory
- org.springframework.core.io.ResourceLoader
- javax.servlet.ServletRequest(本次添加)
- javax.servlet.http.HttpSession(本次添加)
- org.springframework.context.ApplicationEventPublisher
本章节主要是讲解刷新应用上下文的一部分,接下里我们会继续分析在上下文中注册为bean的工厂处理器等,期待你的关注。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)