Spring MVC之基于java config无xml配置的web应用构建

更多spring相关博文参考: http://spring.hhui.top

前一篇博文讲了SpringMVC+web.xml的方式建立web应用,用过SpringBoot的童鞋都知道,早就没有xml什么事情了,其实Spring 3+, Servlet 3+的版本,就已经支持java config,不用再写xml;本篇将介绍下,如何利用java config取代xml配置html

本篇博文,建议和上一篇对比看,贴出上一篇地址java

<!-- more -->git

I. Web构建

1. 项目依赖

对于依赖这一块,和前面同样,不一样的在于java config 取代 xmlgithub

<artifactId>200-mvc-annotation</artifactId>
<packaging>war</packaging>

<properties>
    <spring.version>5.1.5.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.jetty.aggregate</groupId>
        <artifactId>jetty-all</artifactId>
        <version>9.2.19.v20160908</version>
    </dependency>
</dependencies>

<build>
    <finalName>web-mvc</finalName>
    <plugins>
        <plugin>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>9.4.12.RC2</version>
            <configuration>
                <httpConnector>
                    <port>8080</port>
                </httpConnector>
            </configuration>
        </plugin>
    </plugins>
</build>

细心的童鞋会看到,依赖中多了一个jetty-all,后面测试篇幅会说到用法web

2. 项目结构

第二节依然放上项目结构,在这里把xml的结构也截进来了,对于咱们的示例demo而言,最大的区别就是没有了webapp,更没有webapp下面的几个xml配置文件spring

项目结构

3. 配置设定

如今没有了配置文件,咱们的配置仍是得有,否则web容器(如tomcat)怎么找到DispatchServlet呢api

a. DispatchServlet 声明

一样咱们须要干的第一件事情及时声明DispatchServlet,并设置它的应用上下文;能够怎么用呢?从官方找到教程tomcat

{% blockquote @SpringWebMvc教程 https://docs.spring.io/spring... %}服务器

The DispatcherServlet, as any Servlet, needs to be declared and mapped according to the Servlet specification by using Java configuration or in web.xml. In turn, the DispatcherServlet uses Spring configuration to discover the delegate components it needs for request mapping, view resolution, exception handlingmvc

{% endblockquote %}

上面的解释,就是说下面的代码和web.xml的效果是同样同样的

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {
        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("mvc-dispatcher", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }
}

固然直接实现接口的方式有点粗暴,可是好理解,上面的代码和咱们前面的web.xml效果同样,建立了一个DispatchServlet, 而且绑定了url命中规则;设置了应用上下文AnnotationConfigWebApplicationContext

这个上下文,和咱们前面的配置文件mvc-dispatcher-servlet有点像了;若是有兴趣看到项目源码的同窗,会发现用的不是上面这个方式,而是及基础接口AbstractDispatcherServletInitializer

public class MyWebApplicationInitializer extends AbstractDispatcherServletInitializer {
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        //        applicationContext.setConfigLocation("com.git.hui.spring");
        applicationContext.register(RootConfig.class);
        applicationContext.register(WebConfig.class);
        return applicationContext;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/*"};
    }
    
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{new HiddenHttpMethodFilter(), new CharacterEncodingFilter()};
    }
}

看到上面这段代码,这个感受就和xml的方式更像了,好比Servlet应用上下文和根应用上下文

说明

上面代码中增长的Filter先无视,后续会有专文讲什么是Filter以及Filter能够怎么用

b. java config

前面定义了DispatchServlet,接下来对比web.xml就是须要配置扫描并注册bean了,本文基于JavaConfig的方式,则主要是借助 @Configuration 注解来声明配置类(这个能够等同于一个xml文件)

前面的代码也能够看到,上下文中注册了两个Config类

RootConfig定义以下,注意下注解@ComponentScan,这个等同于<context:component-sca/>,指定了扫描并注册激活的bean的包路径

@Configuration
@ComponentScan(value = "com.git.hui.spring")
public class RootConfig {
}

另一个WebConfig的做用则主要在于开启WebMVC

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
}

4. 实例代码

实例和上一篇同样,一个普通的Server Bean和一个Controller

@Component
public class PrintServer {
    public void print() {
        System.out.println(System.currentTimeMillis());
    }
}

一个提供rest服务的HelloRest

@RestController
public class HelloRest {
    @Autowired
    private PrintServer printServer;

    @GetMapping(path = "hello", produces="text/html;charset=UTF-8")
    public String sayHello(HttpServletRequest request) {
        printServer.print();
        return "hello, " + request.getParameter("name");
    }


    @GetMapping({"/", ""})
    public String index() {
        return UUID.randomUUID().toString();
    }
}

5. 测试

测试依然能够和前面同样,使用jetty来启动,此外,介绍另一种测试方式,也是jetty,可是不一样的是咱们直接写main方法来启动服务

public class SpringApplication {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        ServletContextHandler handler = new ServletContextHandler();

        // 服务器根目录,相似于tomcat部署的项目。 完整的访问路径为ip:port/contextPath/realRequestMapping
        //ip:port/项目路径/api请求路径
        handler.setContextPath("/");

        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(WebConfig.class);
        applicationContext.register(RootConfig.class);

        //至关于web.xml中配置的ContextLoaderListener
        handler.addEventListener(new ContextLoaderListener(applicationContext));

        //springmvc拦截规则 至关于web.xml中配置的DispatcherServlet
        handler.addServlet(new ServletHolder(new DispatcherServlet(applicationContext)), "/*");

        server.setHandler(handler);
        server.start();
        server.join();
    }
}

测试示意图以下

测试示意图

6. 小结

简单对比下xml的方式,会发现java config方式会清爽不少,不须要多个xml配置文件,维持几个配置类,加几个注解便可;固然再后面的SpringBoot就更简单了,几个注解了事,连上面的两个Config文件, ServletConfig均可以省略掉

另一个须要注意的点就是java config的运行方式,在servlet3以后才支持的,也就是说若是用比较老的jetty是起不来的(或者没法正常访问web服务)

II. 其余

- 系列博文

web系列:

mvc应用搭建篇:

0. 项目

1. 一灰灰Blog

一灰灰的我的博客,记录全部学习和工做中的博文,欢迎你们前去逛逛

2. 声明

尽信书则不如,以上内容,纯属一家之言,因我的能力有限,不免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

3. 扫描关注

一灰灰blog

QrCode

知识星球

goals

相关文章
相关标签/搜索