Spring BeanPostProcessor : WebApplicationContextServletContextAwareProcessor

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/andy_zhang2007/article/details/86289823

概述

WebApplicationContextServletContextAwareProcessor被用于向bean注入ConfigurableWebApplicationContext应用上下文,它仅仅用在当前应用是一个Springboot + Spring MVC(也就是Servlet)Web应用的情况下。如果当前应用是一个非Spring boot Servlet Web应用,而是一个非Servlet应用,或者非Web的命令行应用,则WebApplicationContextServletContextAwareProcessor根本不会出现在应用上下文中。

WebApplicationContextServletContextAwareProcessor继承自ServletContextAwareProcessor,而ServletContextAwareProcessorSpring MVC Web应用(不一定要基于Springboot)中应用上下文向bean 设置ServletContextBeanPostProcessor。可以认为WebApplicationContextServletContextAwareProcessorServletContextAwareProcessor针对Springboot环境的一个变种,其目的一致。

对比父类ServletContextAwareProcessorWebApplicationContextServletContextAwareProcessor获取ServletContext,ServletConfig的方式有所不同:它先尝试从指定的ConfigurableWebApplicationContext应用上下文中获取ServletContext,ServletConfig,如果获取不到,才使用父类ServletContextAwareProcessor定义的方式再尝试获取ServletContext,ServletConfig。二者向bean设置ServletContext,ServletConfig的逻辑是一样的。

WebApplicationContextServletContextAwareProcessor自己会由应用上下文创建和注册到bean容器,不需要应用开发人员操心。具体注册位置如下:

	// 类 ServletWebServerApplicationContext 代码片段
	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		beanFactory.addBeanPostProcessor(
				new WebApplicationContextServletContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		registerWebApplicationScopes();
	}

相应调用栈举例 :

SpringApplication#run
=> SpringApplication#refresh
==> ServletWebServerApplicationContext#refresh
===> AbstractApplicationContext#refresh
====> AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory
=====> ServletWebServerApplicationContext#postProcessBeanFactory

WebApplicationContextServletContextAwareProcessor 位于包package org.springframework.boot.web.servlet.context

源代码解析

WebApplicationContextServletContextAwareProcessor

package org.springframework.boot.web.servlet.context;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

import org.springframework.util.Assert;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.support.ServletContextAwareProcessor;

/**
 * @author Phillip Webb
 */
public class WebApplicationContextServletContextAwareProcessor
		extends ServletContextAwareProcessor {

	private final ConfigurableWebApplicationContext webApplicationContext;

	public WebApplicationContextServletContextAwareProcessor(
			ConfigurableWebApplicationContext webApplicationContext) {
		Assert.notNull(webApplicationContext, "WebApplicationContext must not be null");
		this.webApplicationContext = webApplicationContext;
	}


	@Override
	protected ServletContext getServletContext() {
		// 先尝试从webApplicationContext中获取ServletContext,如果获取不到
		// 然后再使用父类的方式获取
		ServletContext servletContext = this.webApplicationContext.getServletContext();
		return (servletContext != null) ? servletContext : super.getServletContext();
	}

	@Override
	protected ServletConfig getServletConfig() {
		// 先尝试从webApplicationContext中获取servletConfig ,如果获取不到
		// 然后再使用父类的方式获取
		ServletConfig servletConfig = this.webApplicationContext.getServletConfig();
		return (servletConfig != null) ? servletConfig : super.getServletConfig();
	}

}

ServletContextAwareProcessor

package org.springframework.web.context.support;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.web.context.ServletConfigAware;
import org.springframework.web.context.ServletContextAware;

/**
 * @author Juergen Hoeller
 * @author Phillip Webb
 * @since 12.03.2004
 * @see org.springframework.web.context.ServletContextAware
 * @see org.springframework.web.context.support.XmlWebApplicationContext#postProcessBeanFactory
 */
public class ServletContextAwareProcessor implements BeanPostProcessor {

	@Nullable
	private ServletContext servletContext;

	@Nullable
	private ServletConfig servletConfig;


	/**
	 * Create a new ServletContextAwareProcessor without an initial context or config.
	 * When this constructor is used the #getServletContext() and/or
	 * #getServletConfig() methods should be overridden.
	 */
	protected ServletContextAwareProcessor() {
	}

	/**
	 * Create a new ServletContextAwareProcessor for the given context.
	 */
	public ServletContextAwareProcessor(ServletContext servletContext) {
		this(servletContext, null);
	}

	/**
	 * Create a new ServletContextAwareProcessor for the given config.
	 */
	public ServletContextAwareProcessor(ServletConfig servletConfig) {
		this(null, servletConfig);
	}

	/**
	 * Create a new ServletContextAwareProcessor for the given context and config.
	 */
	public ServletContextAwareProcessor(@Nullable ServletContext servletContext, 
		@Nullable ServletConfig servletConfig) {
		this.servletContext = servletContext;
		this.servletConfig = servletConfig;
	}


	/**
	 * Returns the ServletContext to be injected or null. This method
	 * can be overridden by subclasses when a context is obtained after the post-processor
	 * has been registered.
	 */
	@Nullable
	protected ServletContext getServletContext() {
		if (this.servletContext == null && getServletConfig() != null) {
			return getServletConfig().getServletContext();
		}
		return this.servletContext;
	}

	/**
	 * Returns the  ServletConfig to be injected or  null. This method
	 * can be overridden by subclasses when a context is obtained after the post-processor
	 * has been registered.
	 */
	@Nullable
	protected ServletConfig getServletConfig() {
		return this.servletConfig;
	}

	// BeanPostProcessor 定义的方法,在bean创建时,实例化后,初始化前应用
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// 如果 bean 实现了 ServletContextAware 接口,并且 servletContext 不为 null,
		// 则设置 bean 的 servletContext 属性
		if (getServletContext() != null && bean instanceof ServletContextAware) {
			((ServletContextAware) bean).setServletContext(getServletContext());
		}
		// 如果 bean 实现了 ServletConfigAware 接口,并且 servletConfig 不为 null,
		// 则设置 bean 的 servletConfig 属性
		if (getServletConfig() != null && bean instanceof ServletConfigAware) {
			((ServletConfigAware) bean).setServletConfig(getServletConfig());
		}
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		return bean;
	}

}

猜你喜欢

转载自blog.csdn.net/andy_zhang2007/article/details/86289823