乐趣区

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 配置
本篇博文,建议和上一篇对比看,贴出上一篇地址
190316-Spring MVC 之基于 xml 配置的 web 应用构建
<!– more –>
I. Web 构建
1. 项目依赖
对于依赖这一块,和前面一样,不同的在于 java config 取代 xml
<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,后面测试篇幅会说到用法
2. 项目结构
第二节依然放上项目结构,在这里把 xml 的结构也截进来了,对于我们的示例 demo 而言,最大的区别就是没有了 webapp,更没有 webapp 下面的几个 xml 配置文件

3. 配置设定
现在没有了配置文件,我们的配置还是得有,不然 web 容器(如 tomcat)怎么找到 DispatchServlet 呢
a. DispatchServlet 声明
同样我们需要干的第一件事情及时声明 DispatchServlet,并设置它的应用上下文;可以怎么用呢?从官方找到教程
{% 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 handling
{% 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 系列:
Spring Web 系列博文汇总
mvc 应用搭建篇:

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

0. 项目

工程:spring-boot-demo

项目: https://github.com/liuyueyi/spring-boot-demo/blob/master/spring/200-mvc-annotation

1. 一灰灰 Blog

一灰灰 Blog 个人博客 https://blog.hhui.top

一灰灰 Blog-Spring 专题博客 http://spring.hhui.top

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
2. 声明
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激

微博地址: 小灰灰 Blog

QQ:一灰灰 /3302797840

3. 扫描关注
一灰灰 blog

知识星球

退出移动版