Spring MVC源码解析 - FrameworkServlet

Spring的FrameworkServlet作为Web框架的基础,负责管理WebApplicationContext并处理请求。它支持自定义初始化、配置类以及上下文位置,允许编程式配置。在处理请求时,无论是否成功,都会发布事件。子类需实现doService方法,并可利用initFrameworkServlet进行初始化。默认上下文类为XmlWebApplicationContext,命名空间默认为'servlet-name'-servlet。
摘要由CSDN通过智能技术生成

一. FrameworkServlet

Spring的Web框架的基础servlet。提供了一个Spring应用程序上下文的集成,以一种基于JavaBean的方式。

这个类提供了如下功能:

1. 为每个servlet管理WebApplicationContext实例。Servlet的配置由servlet的命名空间的beans决定。在处理请求的时候,无论请求有没有被成功处理,都会发布事件。

2. 子类必须实现doService方法去处理请求。因为这个直接集成HttpServletBean,而不是HttpServlet,bean属性自动映射到它里面。子类可以重写initFrameworkServlet方法用于自定义初始化。

3. 在servlet的“init-param”中找到 “contextClass”参数 ,作为默认的上下文类。默认的是XmlWebApplicationContext。一个自定义的context class需要实现ConfigurableWebApplicationContext。

4. 接受一个可选择的"contextInitializerClasses" 在 “init-param”中,去指定一个或者多个ApplicationContextInitializer类。Web Application Context委派这些初始化器,允许有额外的编程式的配置。

5. 将"contextConfigLocation"的"init-param"传递给上下文实例,使用逗号和空格分离不同的文件路径。如果没有明确指定,上下文的实现类会从servlet的命名空间建立一个默认的位置。

6. 默认的命名空间是 ‘servlet-name’-servlet,(/WEB-INF/'servlet-name'-servlet.xml)。命名空间可以在servlet的"init-param"中去指定。

7. 在3.1中,FrameworkServlet可以用一个web application context注入,而不是内部创建。


现在来看下FrameworkServlet这个类。

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware

首先它是个抽象类,然后有一个ApplicationContextAware接口。

public interface ApplicationContextAware extends Aware {

	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}
public interface Aware {

}

然后看下它的成员变量,如下:

	/**
	 * web application context的命名空间前缀
	 *
	 */
	public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";

	/**
	 * FrameworkServlet默认的上下文类
	 */
	public static final Class<?> DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;

	/**
	 * WebApplicationContext的ServletContext属性的前缀
	 */
	public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";

	/**
	 * init-param的分隔符
	 */
	private static final String INIT_PARAM_DELIMITERS = ",; \t\n";


	/** ServletContext attribute to find the WebApplicationContext in. */
	@Nullable
	private String contextAttribute;

	/** WebApplicationContext implementation class to create. */
	private Class<?> contextClass = DEFAULT_CONTEXT_CLASS;

	/** WebApplicationContext id to assign. */
	@Nullable
	private String contextId;

	/** Namespace for this servlet. */
	@Nullable
	private String namespace;

	/** Explicit context config location. */
	@Nullable
	private String contextConfigLocation;

	/** Actual ApplicationContextInitializer instances to apply to the context. */
	private final List<ApplicationContextInitializer<ConfigurableApplicationContext>> contextInitializers =
			new ArrayList<>();

	/** Comma-delimited ApplicationContextInitializer class names set through init param. */
	@Nullable
	private String contextInitializerClasses;

	/** Should we publish the context as a ServletContext attribute?. */
	private boolean publishContext = true;

	/** Should we publish a ServletRequestHandledEvent at the end of each request?. */
	private boolean publishEvents = true;

	/** Expose LocaleContext and RequestAttributes as inheritable for child threads?. */
	private boolean threadContextInheritable = false;

	/** Should we dispatch an HTTP OPTIONS request to {@link #doService}?. */
	private boolean dispatchOptionsRequest = false;

	/** Should we dispatch an HTTP TRACE request to {@link #doService}?. */
	private boolean dispatchTraceRequest = false;

	/** Whether to log potentially sensitive info (request params at DEBUG + headers at TRACE). */
	private boolean enableLoggingRequestDetails = false;

	/** 这个servlet的WebApplicationContext */
	@Nullable
	private WebApplicationContext webApplicationContext;

	/** If the WebApplicationContext was injected via {@link #setApplicationContext}. */
	private boolean webApplicationContextInjected = false;

	/** onRefresh是否已经被调用 */
	private volatile boolean refreshEventReceived = false;

	/** 管理同步onRefresh执行. */
	private final Object onRefreshMonitor = new Object();

然后构造器:

        public FrameworkServlet() {
	}

	
	public FrameworkServlet(WebApplicationContext webApplicationContext) {
		this.webApplicationContext = webApplicationContext;
	}

最后看下它的方法(setter、getter方法这里不讨论)

	/**
	 * 在任何bean属性设置后被调用。创建webapplicationcontext
	 */
	@Override
	protected final void initServletBean() throws ServletException {
		getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
		if (logger.isInfoEnabled()) {
			logger.info("Initializing Servlet '" + getServletName() + "'");
		}
		long startTime = System.currentTimeMillis();

		try {
			this.webApplicationContext = initWebApplicationContext();
			initFrameworkServlet();
		}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值