zoukankan      html  css  js  c++  java
  • 使用JavaConfig和注解方式实现零xml配置的Spring MVC项目

    1. 引言

    Spring MVC是Spring框架重要组成部分,是一款非常优秀的Web框架。Spring MVC以DispatcherServlet为核心,通过可配置化的方式去处理各种web请求。

    在平时项目开发中,通常在web.xml下配置元素,但是我希望尝试通过实现WebApplicationInitilalizer接口来实现无web.xml的方式去搭建一个Spring MVC项目。

    2. Spring MVC 项目的搭建

    2.1 构建Maven项目

    pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>org.aming</groupId>
    	<artifactId>springmvc1</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>war</packaging>
    
    	<properties>
    		<!-- Generic properties -->
    		<java.version>1.8</java.version>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<!-- Web -->
    		<jsp.version>2.2</jsp.version>
    		<jstl.version>1.2</jstl.version>
    		<servlet.version>3.1.0</servlet.version>
    		<!-- Spring -->
    		<spring.version>4.1.5.RELEASE</spring.version>
    		<!-- Logging -->
    		<logback.version>1.0.13</logback.version>
    		<slf4j.version>1.7.5</slf4j.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>javax</groupId>
    			<artifactId>javaee-web-api</artifactId>
    			<version>7.0</version>
    			<scope>provided</scope>
    		</dependency>
    		<!-- Spring MVC -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-webmvc</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<!-- 其他Web依赖 -->
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>jstl</artifactId>
    			<version>${jstl.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>javax.servlet-api</artifactId>
    			<version>${servlet.version}</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet.jsp</groupId>
    			<artifactId>jsp-api</artifactId>
    			<version>${jsp.version}</version>
    		</dependency>
    
    		<!-- Spring -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-tx</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-core</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-beans</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context-support</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    
    		<!-- 使用SLF4J和Logback作为日志 -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-api</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    		<!-- 代码直接调用log4j会被桥接到slf4j -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>log4j-over-slf4j</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    		<!-- 代码直接调用commons-logging会被桥接到slf4j -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>jcl-over-slf4j</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    		<!-- 代码直接调用java.util.logging会被桥接到slf4j -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>jul-to-slf4j</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    		<!-- log4jdbc -->
    		<dependency>
    			<groupId>com.googlecode.log4jdbc</groupId>
    			<artifactId>log4jdbc</artifactId>
    			<version>1.2</version>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-classic</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-core</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-access</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<finalName>springmvc</finalName>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>2.5.1</version>
    				<configuration>
    					<source>${java.version}</source>
    					<target>${java.version}</target>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-war-plugin</artifactId>
    				<version>2.3</version>
    				<configuration>
    					<failOnMissingWebXml>false</failOnMissingWebXml>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>
    

    2.1 日志配置

    我们使用logback去管理我们的日志,相比去log4j,logback性能更为出色。我们在src/main/reources目录下,新建logback.xml,其内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="1 seconds">
    	<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
    		<resetJUL>true</resetJUL>
    	</contextListener>
    	
    	<jmxConfigurator/>
    	
    	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    		<encoder>
    			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符--> 
    			<pattern>
    				%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%method - [%X{logback}] - %msg%n
    			</pattern>
    		</encoder>
    	</appender>
    	
    	<logger name="org.springframework.web" level="DEBUG"/>
    	
    	<root level="info">
    		<appender-ref ref="console"/>
    	</root>
    </configuration>
    

    说明:在开发Spring MVC的过程中经常出现和参数类型相关的4XX错误,将org.springframework.web包下的类的日志级别设置为debug可以看到更详细的错误信息。

    2.3 演示页面

    在src/main/resources下建立views目录,并在此目录下新建index.jsp,body元素中添加以下内容:

        <pre>
            Welcome to Spring MVC world
        </pre>
    

    说明:

    1. 在Maven标准中,页面通常放在src/main/webapp/WEB-INF下,此处这样放置页面的主要目的是和Spring Boot的页面放置方式保持一致;
    2. 在ecplise中新建jsp页面默认是在webapp中,即使是在src/main/resources下目录点击新建,因此在新建jsp时需要重新选择合适的目录。

    2.4 Spring MVC 配置

    新建ApplicationConfiguration类作为Spring MVC的配置类,其内容如下:

    @Configuration
    @EnableWebMvc
    @ComponentScan("org.aming.demo.springmvc")
    public class ApplicationConfiguration {
    	
    	@Bean
    	public InternalResourceViewResolver viewResolver() {
    		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    		//运行时代码会将位于src/main/resources目录下的页面自动编译到/WEB-INF/classes/views/下
            //如果是src/main/webapp/WEB-INF的页面,那么prefix是/WEB-INF/views/
    		viewResolver.setPrefix("/WEB-INF/classes/views/");
    		viewResolver.setSuffix(".jsp");
    		viewResolver.setViewClass(JstlView.class);
    		return viewResolver;
    	}
    }
    

    说明:

    1. @Configuration注解表明ApplicationConfiguration是一个普普通通配置类;
    2. @EnableWebMvc注解会开启一些默认配置,如一些ViewResolver或者MessageConverter等;
    3. @ComponentScan注解将会扫描指定包下通过注解配置的bean。

    2.5 Web配置

    新建WebInitializer类并实现WebApplicationInitializer接口:

    public class WebInitializer implements WebApplicationInitializer {
    
    	@Override
    	public void onStartup(ServletContext servletContext) throws ServletException {
    		AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    		 ctx.register(ApplicationConfiguration.class);
    		 ctx.setServletContext(servletContext);
    		 Dynamic servlet = servletContext.addServlet("dispatcher",new DispatcherServlet(ctx));
    		 servlet.addMapping("/");
    		 servlet.setLoadOnStartup(1);
    	}
    }
    

    说明:

    1. WebApplicationInitializer是Spring提供用来配置Servlet3.0+配置的接口,从而实现了替代web.xml的位置。实现此接口将会自动被SpringServletContainerInitializer(用来启动Servlet3.0容器)获取到。
    2. 新建WebApplicationContext,注册配置类(ApplicationConfiguration),并和其和当前servletContext关联
    3. 注册Spring MVC的DispatcherServlet。

    2.6 简单控制器

    新建HelloController类去完成URL和方法之间的映射:

    @Controller
    public class HelloController {
    	@RequestMapping("/index")
    	public String hello() {
    		return "index";
    	}
    }
    

    3. 运行结果

    将项目打成war包部署到tomcat中,启动tomcat,在浏览器中输入:http://127.0.0.1:8080/springmvc/index
    运行结果截图

    4. 参考书籍

    汪云飞:JavaEE开发的颠覆者:Spring Boot实战

  • 相关阅读:
    leetcode 350. Intersection of Two Arrays II
    leetcode 278. First Bad Version
    leetcode 34. Find First and Last Position of Element in Sorted Array
    leetcode 54. Spiral Matrix
    leetcode 59. Spiral Matrix II
    leetcode 44. Wildcard Matching
    leetcode 10. Regular Expression Matching(正则表达式匹配)
    leetcode 174. Dungeon Game (地下城游戏)
    leetcode 36. Valid Sudoku
    Angular Elements
  • 原文地址:https://www.cnblogs.com/xiao2/p/7411854.html
Copyright © 2011-2022 走看看