目錄
1、AbstractRefreshableWebApplicationContext
1)、ServletContextAwareProcessor
2)、registerWebApplicationScopes
2、AnnotationConfigServletWebServerApplicationContext
1)、WebApplicationContextServletContextAwareProcessor
2)、registerWebApplicationScopes
3、AnnotationConfigReactiveWebServerApplicationContext
postProcessBeanFactory
允許在上下文子類中對bean工廠進行後處理,AbstractApplicationContext中方法爲空,實現的基本都是Web相關的子類,對javax.servlet.ServletContext、javax.servlet.ServletConfig以及Scope爲(Request、application)的處理。
1、AbstractRefreshableWebApplicationContext
Spring Boot之前的Web類型項目,就會在該父類(AbstractRefreshableWebApplicationContext)中實現該方法,而當前的servletContext和servletConfig信息會在web.xml初始化時傳過來,在後面SpringMVC中進行分析。其子類有:
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
1)、ServletContextAwareProcessor
添加了一個ServletContextAwareProcessor類型的BeanPostProcessor,只是添加調用在後面。如果Bean實現了ServletContextAware或者ServletConfigAware,則會在生命週期的中回調設置servletContext和servletConfig信息,回調實現正是ServletContextAwareProcessor,所以需要添加忽略接口。
2)、registerWebApplicationScopes
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
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.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);
}
}
在WebApplicationContextUtils中,註冊Scope信息RequestScope和SessionScope,到AbstractApplicationContext的scopes中。但是基本都會使用singleton類型的scope,所以就不分析了。registerResolvableDependency註冊Servlet相關依賴。
3)、registerEnvironmentBeans
也是在WebApplicationContextUtils中,將ServletContext相關的環境注入爲Bean。servletContext、servletConfig、contextParameters、contextAttributes。
public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,
@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
}
if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
Map<String, String> parameterMap = new HashMap<>();
if (servletContext != null) {
Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, servletContext.getInitParameter(paramName));
}
}
if (servletConfig != null) {
Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
while (paramNameEnum.hasMoreElements()) {
String paramName = (String) paramNameEnum.nextElement();
parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
Collections.unmodifiableMap(parameterMap));
}
if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
Map<String, Object> attributeMap = new HashMap<>();
if (servletContext != null) {
Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
while (attrNameEnum.hasMoreElements()) {
String attrName = (String) attrNameEnum.nextElement();
attributeMap.put(attrName, servletContext.getAttribute(attrName));
}
}
bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
Collections.unmodifiableMap(attributeMap));
}
}
2、AnnotationConfigServletWebServerApplicationContext
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// super爲AbstractApplicationContext,爲空方法
super.postProcessBeanFactory(beanFactory);
if (!ObjectUtils.isEmpty(this.basePackages)) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
當爲初始化Spring boot類型時候,
SpringApplication springApplication = new SpringApplication(KevinToolApplication.class);
springApplication.setWebApplicationType(WebApplicationType.SERVLET);
springApplication.run(args);
初始化AnnotationConfigReactiveWebServerApplicationContext類型,並且當前basePackages和annotatedClasses都爲空,父類ServletWebServerApplicationContext中方法如下
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes();
}
ServletContextAware添加到忽略,同上面相同。
1)、WebApplicationContextServletContextAwareProcessor
父類是ServletContextAwareProcessor並且實現了接口BeanPostProcessor,那麼在bean實現了該接口回調時,父類的postProcessBeforeInitialization中會回調setServletContext和setServletConfig方法,將Servlet信息進行注入。
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (getServletContext() != null && bean instanceof ServletContextAware) {
((ServletContextAware) bean).setServletContext(getServletContext());
}
if (getServletConfig() != null && bean instanceof ServletConfigAware) {
((ServletConfigAware) bean).setServletConfig(getServletConfig());
}
return bean;
}
2)、registerWebApplicationScopes
private void registerWebApplicationScopes() {
ExistingWebApplicationScopes existingScopes = new
ExistingWebApplicationScopes(getBeanFactory());
WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
existingScopes.restore();
}
3、AnnotationConfigReactiveWebServerApplicationContext
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// super爲AbstractApplicationContext,爲空方法
super.postProcessBeanFactory(beanFactory);
if (!ObjectUtils.isEmpty(this.basePackages)) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
當爲初始化Spring boot類型時候,
SpringApplication springApplication = new SpringApplication(KevinToolApplication.class);
springApplication.setWebApplicationType(WebApplicationType.REACTIVE);
springApplication.run(args);
初始化AnnotationConfigReactiveWebServerApplicationContext類型,只是父類AbstractApplicationContext中該方法爲空,並且當前basePackages和annotatedClasses都爲空。