零配置文件搭建SpringMVC实践纪录

摘要:
本文记录了使用纯Java代码构建SpringMVC项目的实践,这只是一个演示。SpringMVC的“零配置”就是基于这个特性。接下来,让我们逐步构建SpringMVC。上图显示了启动键类的初始化过程。首先,容器启动、初始化并执行实现ServletContainerInitializer接口的Spring类。此类初始化实现WebApplicationInitializer接口的PlayWebAppInitializer类。

   本篇记录使用纯java代码搭建SpringMVC工程的实践,只是一个demo。再开始之前先热身下,给出SpringMVC调用流程图,讲解的是一个http request请求到达SpringMVC框架后的过程,如下:

零配置文件搭建SpringMVC实践纪录第1张

从servlet 3.0开始,实现javax.servlet.ServletContainerInitializer接口的类将在容器启动的时候执行onStartup方法。SpringMVC的”零配置”就是基于这个特性。所以对于servlet 3.0 以下的容器还是老老实实在web.xml中进行配置。 下面让我们一步步搭建SpringMVC,先上图:

零配置文件搭建SpringMVC实践纪录第2张

  上图中展示了启动关键类的初始化过程,首先容器启动,初始化并执行实现ServletContainerInitalzer接口的Spring类,该类初始化实现WebApplicationInitializer接口的PlayWebAppInitializer类(由于这里继承了AbstractAnnotationConfigDispatcherServletInitializer抽象类)。

   在讲解PlayWebAppInitializer初始化了两个bean容器,一种是与DispatcherServlet相关联的MVC框架直接关系的bean,如:Controller,Service,Repository等等。再说另外一种bean容器前先回忆下,还记得ContextLoaderListener吧,做SSH框架整合时在web.xml中要配置这个类,所以说这个容器是配置更通用一些的bean。 那么问题来了:为什么要有两个共存呢?----答:我猜想是方便分离,如果不想使用SpringMVC而实用其他MVC框架的可以把DispatcherServlet相关的那个bean容器拿掉。(纯属意淫,欢迎拍砖)。

  这里WebConfig用来负责DispacherServlet相关bean的配置,RootConfig用来负责ContextLoaderListener相关bean的配置。

下面截取一段《Spring in Action 4th》中关于两个ApplicationContext的原话,在135页:

A TALE OF TWO APPLICATION CONTEXTS

When DispatcherServlet starts up, it creates a Spring application context and starts loading it with beans declared in the configuration files or classes that it’s given. With the getServletConfigClasses() method in listing 5.1, you’ve asked that Dispatcher- Servlet load its application context with beans defined in the WebConfig configura- tion class (using Java configuration). But in Spring web applications, there’s often another application context. This other application context is created by ContextLoaderListener. Whereas DispatcherServlet is expected to load beans containing web components such as controllers, view resolvers, and handler mappings, ContextLoaderListener is expected to load the other beans in your application. These beans are typically the middle-tier and data-tier components that drive the back end of the application. 136 CHAPTER 5 Building Spring web applications Under the covers, AbstractAnnotationConfigDispatcherServletInitializer cre- ates both a DispatcherServlet and a ContextLoaderListener. The @Configuration classes returned from getServletConfigClasses() will define beans for Dispatcher- Servlet’s application context. Meanwhile, the @Configuration class’s returned get- RootConfigClasses() will be used to configure the application context created by ContextLoaderListener. In this case, your root configuration is defined in RootConfig, whereas Dispatcher- Servlet’s configuration is declared in WebConfig. You’ll see what those two configura- tion classes look like in a moment.

上实践的代码: com.bob.playspring.PlayWebAppInitializer

package com.bob.playspring;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * 初始化DispatherServlet,代替在web.xml中到DispatherServlet配置,
 * @author bob
 *
 */
public class PlayWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebConfig.class };
    }

    /**
     * identifies one or more paths that DispatcherServlet will be mapped to.<br>
     *  In this case, it’s mapped to /, indicating that it will be the application’s default servlet.<br>
     *   It will handle all requests coming into the application.
     */
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}

com.bob.playspring.WebConfig

package com.bob.playspring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * 系统配置
 * @author bob
 *
 */
@EnableWebMvc
@Configuration
@ComponentScan("com.bob")
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

}

com.bob.playspring.RootConfig

package com.bob.playspring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages = { "com.bob" }, excludeFilters = {
        @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig {

}

关于Controller,Service,Repository的代码我就不贴了。

免责声明:文章转载自《零配置文件搭建SpringMVC实践纪录》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于《设计模式演练》系列文章结构的规范为什么JAVA的垃圾回收机制无法避免内存泄漏下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JNDI简介和简单示例

什么是JNDI? The Java Naming and Directory Interface是访问不同名字和目录服务的统一API接口。 不同的服务使用不同的名字格式。 Java程序需要以相同的格式访问数据库,文件,目录,对象和网络。 JNID有两部分接口:应用程序接口和提供服务的接口。在应用程序中使用API来访问名字或目录服务,在一个新的服务中使用SP...

单例模式详解

参考: https://www.cnblogs.com/happy4java/p/11206105.html https://blog.csdn.net/jason0539/article/details/23297037 https://blog.csdn.net/justloveyou_/article/details/64127789 https://...

策略模式

策略模式:帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其他对象中的算法。 举个例子: 我们常用的加密算法有DES(对称加密)和AES(非对称加密),假如现在我们有一个报文Context需要加密,加密的方法不固定,可能使用DES,也可能使用AES,实现这个需求有两种方法。 第一种方法就是在Context类中定义两个加密算法(DES和AES),然后...

python中的类变量

类变量: 即类使用的变量,类方法以及构造函数以外的变量 其值的修改有两种情况 通过调用 类名.变量名 来修改其效果是:使得类的变量被修改,后续新建立的对象的类变量名就会是修改后的值。可以使用的场景:比如:用在初始化里面,每新建一个对象(初始化一次的时候),使类变量+1,就可以通过 类名.变量名 来查看此类被实例化的对象数量 通过对象内修改。其效果与 实...

Mybatis-Plus的使用

1.什么是Mybatis-Plus 2.为什么要学习Mybatis-Plus 3.入门示例 3.1 说明 3.2 准备工作 3.3 配置步骤 4.常用配置 4.1 实体类全局配置 4.2.插件配置(配置分页插件) 5.自定义方法 6.Service 层 1.什么是Mybatis-Plus MyBatis-Plus(简称 MP)是一个MyB...

Android 开发-----数据存储

数据一般有以下保存方式实现: SharedPreferences 采用java.io.* 库所提供的I/O 接口,读写文件。 SQLite 数据库 ContentProvider 一.SharedPreferences SharedPreferences是一种轻量级的数据保存方式,比较类似于我们常用的ini文件,用来保存运用程序的一些属性设置,较简单的参...