SpringMVC之器

本章分析SpringMVC自身的创建过程,首先分析SpringMVC的整体结构,然后具体分析每一层的创建过程

整体结构介绍

在Servlet的继承结构中一共有5个类,GenericServlet和HttpServlet在java中
剩下的三个类HttpServletBean、FrameworkServlet和DispatcherServlet是SpringMVC中的
这三个类直接实现三个接口:EnvironmentCapable、EnvironmentAware和ApplicationContextAware。
XXXAware在spring里表示对XXX可以感知,通俗点解释就是:如果在某个类里面想要使用spring的一些东西,就可以通过实现XXXAware接口告诉spring,spring看到后就会给你送过来,而接收的方式是通过实现接口唯一的方法setXXX
比如,有一个类想要使用当前的ApplicationContext,那么我们只需要让它实现ApplicationContextAware接口,然后实现接口中唯一的方法,void setApplicationContext(ApplicationContext applicationContext(会自动传过来,直接用))就可以了,spring会自动调用这个方法将applicationContext传给我们,我们只需要接收就可以了。
EnvironmentCapable,顾名思义,当然就是具有Environment的能力,也就是可以提供Environment,所以EnvironmentCapable唯一的方法是Environment getEnvironment()
用于实现EnvironmentCapable接口的类,就是告诉spring它可以提供Environment,当spring需要Environment的时候就会调用其getEnvironment方法跟它要。

HttpServletBean

Servlet创建时可以直接调用无参数的init方法
在HttpServletBean的init方法中,首先将Servlet中配置的参数使用BeanWrapper设置到DispatcherServlet的相关属性,然后调用模板方法initServletBean,子类就通过这个方法初始化

BeanWrapper是什么,怎么用
BeanWrapper是Spring 提供的一个用来操作JavaBean属性的工具,使用它可以直接修改一个对象的属性

public class User{
	String userName;
	//省略get和set方法
}
public class BeanWrapperTest{
	psvm{
		User user = new User();
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(user);
		bw.setPropertyValue("userName","张三");
		sout(user.getUserName());
		PropertyValue value = new PropertyValue("userName","李四");
		sout(user.getUserName());
	}
}
使用反射

FrameworkServlet

FrameworkServlet继承HttpServletBean,FrameworkServlet的初始化入口方法是initServletBean

// org.springframework.web.servlet.FrameworkServlet
protected final void initServletBean() throws ServletException{
	//初始化WebApplicationContext
	this.webApplicationContext = initWebApplicationContext();
	//模板方法,子类可以覆盖在里面做一些初始化的工作
	initFrameworkServlet();
}

protected WebApplicationContext initWebApplicationContext(){
	//获取rootContext
	WebApplicationContext rootContext = WebApplicationContextUtils.getApplictionContext(getServletContext());
	WebApplicationContext  wac = null;
	//如果已经通过构造方法设置了webApplicationContext
	if(this.webApplicationContext != null){
		wac = this.webApplicationContext;
		if(wac instanceof ConfigurableWebApplicationContext){
			ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext ) wac;
			if(!cwac.isActive()){
				if(cwac.getParent() == null){
					cwac.setParent(rootContext);
				}
				configureAndRefreshWebApplicationContext(cwac)
			}
		}
	}
	if(wac == null){
		//当webApplicationContext已经存在ServletContext中时,通过配置在Servlet中的contextAttribute参数获取
		wac = findWebApplicationContext();
	}
	if(wac == null)[
		//如果webApplicationContext还没有创建,则创建一个
		wac = createWebApplicationContext(rootContext);
	}
	if(!this.refreshEventReceived){
		//当ContextRefreshedEvent事件没有触发时调用此方法,模板方法,可以在子类重写
		onRefresh(wac);
	}
	if(this.publicContext){
		//将ApplicationContext保存到ServletContext中
		String attrName = getServletContextAttributeName();
		getServletContext().setAttribute(attrName,wac);
	}
	return wac;
}

这个initWebApplicationContext方法做了三件事
1.获取spring的根容器rootContext
获取根容器的原理是,默认情况下spring会将自己的容器设置成ServletContext属性,默认根容器的key为org.springframework.web.context.WebApplicationContext.ROOT
所以获取根容器只需要调用ServletContext的getAttribute就可以了
ServletContext.getAttribute(“org.springframework.web.context.WebApplicationContext.ROOT”);
2.设置webApplicationContext并根据情况调用onRefresh方法
3.将webApplicationContext设置到ServletContext中

DispatcherServlet

OnRefresh方法是DispathcerServlet的入口方法,OnRefresh中简单地调用了initStrategis,在initStrategies中调用了9个初始化方法

//org.springframework.web.servlet.DispatcherServlet
protected void onRefresh (ApplicationContext context){
	initStrategies(context);
}

protected void initStrategies(Application context){
	initMultipartResolver(context);
	initLocalResolver(context);
	initThemeResolver(context);
	initHandlerMappings(context);
	initHandlerAdapters(context);
	initHandlerExceptionResolvers(context);
	initRequestToViewNameTranslator(context);
	initViewResolvers(context);
	initFlashMapManager(context);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值