目录
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
都为空。