SpringMVC框架的一些底层
来源:互联网 发布:php软件下载 编辑:程序博客网 时间:2024/05/16 04:03
SpringMVC框架的一些底层
- SpringMVC的init()
SpingMVC加载过程
类结构图
首先看一下这个结构图,DispatcherServlet是SpringMVC的核心控制器,他遵循了Servlet规范.
虽然现在是一个高大上的框架,但是这三个重要方法肯定是不能忽视的..
第一步:初始化位于HttpServletBean当中的init()方法,因为他是对接Servlet容器体系中传入进来的参数.首先先看一下HttpServletBean中的init()方法:
public final void init() throws ServletException { if(this.logger.isDebugEnabled()) { this.logger.debug("Initializing servlet '" + this.getServletName() + "'"); } //配置文件的信息在ServletConfig中,用这个来初始化SpringMVC框架. //requiredProperties,必须的参数属性,如果没有,抛异常. PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties); if(!pvs.isEmpty()) { try { BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment())); this.initBeanWrapper(bw); bw.setPropertyValues(pvs, true); } catch (BeansException var4) { if(this.logger.isErrorEnabled()) { this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4); } throw var4; } } //模版方法,让子类FrameworkServlet具体实现 //初始化SpringMVC框架的Bean组件 Controller... 九大组件 this.initServletBean(); if(this.logger.isDebugEnabled()) { this.logger.debug("Servlet '" + this.getServletName() + "' configured successfully"); } }
第二步:初始化Bean组件
protected final void initServletBean() throws ServletException { ..... try { //初始化Bean , 构造SpringMVC自己的上下文 this.webApplicationContext = this.initWebApplicationContext(); this.initFrameworkServlet(); } ...... } }
获取Spring的根上下文.
根据当前的SpringMVC上下文:
不为空,进行设置双亲环境,刷新(将SpingMVC上下文激活);
为空,创建SpringMVC上下文,设置双亲环境,配置信息载入,刷新(将SpingMVC上下文激活).
//构造SpringMVC的上下文环境 protected WebApplicationContext initWebApplicationContext() { //通过工具类获取根上下文环境,请注意:1是通过ServletContext拿的,所以再 次印证了外层是ServletContext,里层是一个root也就是WebApplicationContext的上下文环境.此时还没有SpringMVC的上下文. WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); WebApplicationContext wac = null; if(this.webApplicationContext != null) { wac = this.webApplicationContext; //如果是ConfigurableWebApplicationContext这个的一个实现类,强转,然后判断是否激活 if(wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac; if(!cwac.isActive()) { //没有被激活 if(cwac.getParent() == null) { //上下文是双亲体系 cwac.setParent(rootContext); } //激活! this.configureAndRefreshWebApplicationContext(cwac); } } } if(wac == null) { wac = this.findWebApplicationContext(); } if(wac == null) { wac = this.createWebApplicationContext(rootContext); } if(!this.refreshEventReceived) { this.onRefresh(wac); } if(this.publishContext) { String attrName = this.getServletContextAttributeName(); //这里将SpingMVC的上下文环境设置到了ServletContext上,所以我们才可以根据ServletContext获取SpringMVC上下文. this.getServletContext().setAttribute(attrName, wac); if(this.logger.isDebugEnabled()) { this.logger.debug("Published WebApplicationContext of servlet '" + this.getServletName() + "' as ServletContext attribute with name [" + attrName + "]"); } } return wac; }
在FrameworkServlet中有个内部类ContextRefreshListener 用于监听
private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> { private ContextRefreshListener() { } public void onApplicationEvent(ContextRefreshedEvent event) { FrameworkServlet.this.onApplicationEvent(event); } }
public void onApplicationEvent(ContextRefreshedEvent event) { this.refreshEventReceived = true; this.onRefresh(event.getApplicationContext()); }
initWebApplicationContext方法,会根据refreshEventReceived标志来判断是否要远行onRefresh方法.
//创建一个WebApplicationContext protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) { //获取创建类型 Class<?> contextClass = this.getContextClass(); if(this.logger.isDebugEnabled()) { this.logger.debug("Servlet with name '" + this.getServletName() + "' will try to create custom WebApplicationContext context of class '" + contextClass.getName() + "', using parent context [" + parent + "]"); } if(!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Fatal initialization error in servlet with name '" + this.getServletName() + "': custom WebApplicationContext class [" + contextClass.getName() + "] is not of type ConfigurableWebApplicationContext"); } else { //这里使用的DEFAULT_CONTEXT_CLASS设置为XmlWebApplicationContext.class,所以DispatcherServlet中使用的上下文是XmlWebApplicationContext ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass); wac.setEnvironment(this.getEnvironment()); //配置双亲上下文,就是再ContextLoader中建立的上下文 wac.setParent(parent); //将contextConfigLocation 参数传给wac,默认传入WEB-INFO/[ServletName]-servlet.xml (配置文件的路径) wac.setConfigLocation(this.getContextConfigLocation()); //刷新当前上下文 this.configureAndRefreshWebApplicationContext(wac); return wac; } }
总结:
1.获取Spring的根容器rootContext . (获取根据容器的原理是默认情况下Spring会将自己的容器设置成ServletContext的属性,默认根容器的key 定义在org.springframework.web.context.WebApplicationContext 中,String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE =WebApplicationContext.class.getName() + “.ROOT” , 所以获取根容器只需要调用ServletContext的getAttribute就可以了 ServletContext getAttribute(“org.springframework.web.context.WebApplicationContext.ROOT”))
2.设置WebApplicationContext并根据情况调用,onRefresh方法.(设置WebApplication一共有三种方法,第一种是构造方法中传入WebApplication参数,主要用于Servlet3.0以后的环境中,在Servlet3.0之后,可以在程序中用ServletContext.addServlet方式注册Servlet,这时就可以新建FrameworkServlet 第二种方法是WebApplicationContext已经在ServletContext中了,这时只需要在配置Servlet的时候将ServletContext中的webApplicationContext的name配置到contextAttribute上 第三种是前两种方法都无效的情况下自己创建一个,正常情况下就用的这种方式,创建过程在createWebApplicationContext中)
protected void onRefresh(ApplicationContext context) { this.initStrategies(context); }
初始化SpingMVC上下文环境的九大组件…
protected void initStrategies(ApplicationContext context) { this.initMultipartResolver(context); this.initLocaleResolver(context); this.initThemeResolver(context); this.initHandlerMappings(context); this.initHandlerAdapters(context); this.initHandlerExceptionResolvers(context); this.initRequestToViewNameTranslator(context); this.initViewResolvers(context); this.initFlashMapManager(context); }
- SpringMVC的service()
- SpringMVC框架的一些底层
- 服务器底层网络框架设计的一些思考
- 服务器底层网络框架设计的一些思考
- 服务器底层网络框架设计的一些思考
- springmvc框架原理的一些理解
- SpringMVC框架的一些优点和理解
- 搭建springmvc+hibernate+spring框架时遇到的一些错误
- 一些单片机的底层论坛
- 开发自己的底层框架
- SpringMVC与底层数据库的交互
- 【SpringMVC框架】springmvc的基础知识
- 【SpringMVC框架】springmvc的基础知识
- 【SpringMVC框架】springmvc的基础知识
- Springmvc 的一些操作
- springMVC的一些学习
- springmvc的一些笔记
- SpringMVC的一些注解
- springmvc框架的使用
- 2-5 平方根求和
- 2-6 求给定序列前 n 项和(1!+2!+...)
- Python面向对象
- vue.js开发环境搭建
- BAT某公司的一套面试题
- SpringMVC框架的一些底层
- 安卓的录音在iOS端无法播放问题
- (四)指令重复
- Docker核心原理解读(一)
- 基于C语言的简易计算器
- 循环语句和字符串的运用
- 操作博。1,如何extends Servlet和httpServlet解决2.如何引入@Test@Before等
- ElstaticSearch windows搭建
- SQLServer中查询表结构(表主键 、列说明、列数据类型、所有表名)的Sql语句