快速搭建SSM工程
XML文件配置SSM
创建工程
创建一个普通的maven工程,并添加SpringMVC依赖
1 2 3 4 5 6 7
| <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.6</version> </dependency> </dependencies>
|
添加Spring配置
工程创建成功之后,首先添加 Spring 的配置文件,如下:
applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.cwz" use-default-filters="true"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
|
添加SpringMVC配置
创建 springmvc 的配置文件spring-servlet.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.cwz" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
<mvc:annotation-driven/>
</beans>
|
配置web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
|
测试
添加一个 HelloController进行测试
HelloController.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.cwz.controller;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
@RestController public class HelloController {
@Autowired HelloService helloService;
@GetMapping("/hello") public String hello() { String hello = helloService.hello(); System.out.println("hello = " + hello); return "hello ssm"; }
}
|
HelloService.java:
1 2 3 4 5 6 7 8 9 10 11
| package com.cwz.controller;
import org.springframework.stereotype.Service;
@Service public class HelloService { public String hello() { return "hello service"; } }
|
Java配置SSM
在Spring Boot项目中,正常来说不存在XML配置,这是因为Spring Boot不推荐使用XML,但并非不支持,Spring Boot推荐开发者使用Java配置来搭建框架。在Spring Boot中,大量的自动化配置都是Java配置来实现的。这一套实现方案,我们可以自己做,使用纯Java来搭建一个SSM环境。
环境要求:
- 使用纯 Java 来搭建 SSM 环境,要求 Tomcat 的版本必须在 7 以上
添加依赖
1 2 3 4 5 6 7 8 9 10 11 12
| <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.6</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> </dependencies>
|
添加Spring配置
添加 Spring 的配置文件,如下
1 2 3 4 5 6 7 8 9 10 11
| package com.cwz.config;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller;
@Configuration @ComponentScan(basePackages = "com.cwz", useDefaultFilters = true, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)}) public class SpringConfig { }
|
关于这个配置:
- @Configuration 注解表示这是一个配置类,在我们这里,这个配置的作用类似于 applicationContext.xml
- @ComponentScan 注解表示配置包扫描,里边的属性和 xml 配置中的属性都是一一对应的,useDefaultFilters 表示使用默认的过滤器,然后又除去 Controller 注解,即在 Spring 容器中扫描除了 Controller 之外的其他所有 Bean 。
添加SpringMVC配置
1 2 3 4 5 6 7 8 9 10 11
| package com.cwz.config;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller;
@Configuration @ComponentScan(basePackages = "com.cwz", useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class), @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)}) public class SpringMVCConfig { }
|
注意,如果不需要在 SpringMVC 中添加其他的额外配置,这样就可以了。即 视图解析器、JSON 解析、文件上传……等等,如果都不需要配置的话,这样就可以了。
配置web.xml
此时,我们并没有 web.xml 文件,这时,我们可以使用 Java 代码去代替 web.xml 文件,这里会用到 WebApplicationInitializer ,具体定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.cwz.config;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletException; import javax.servlet.ServletRegistration;
public class WebInit implements WebApplicationInitializer { @Override public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMVCConfig.class); ServletRegistration.Dynamic springmvc = servletContext.addServlet("springmvc", new DispatcherServlet(ctx)); springmvc.addMapping("/"); springmvc.setLoadOnStartup(1);
} }
|
WebInit 的作用类似于 web.xml,这个类需要实现 WebApplicationInitializer 接口,并实现接口中的方法,当项目启动时,onStartup 方法会被自动执行,我们可以在这个方法中做一些项目初始化操作,例如加载 SpringMVC 容器,添加过滤器,添加 Listener、添加 Servlet 等。
需要注意的是:
由于我们在 WebInit 中只是添加了 SpringMVC 的配置,这样项目在启动时只会去加载 SpringMVC 容器,而不会去加载 Spring 容器,如果一定要加载 Spring 容器,需要我们修改 SpringMVC 的配置,在 SpringMVC 配置的包扫描中也去扫描 @Configuration 注解,进而加载 Spring 容器 或者 直接在项目中舍弃 Spring 配置,直接将所有配置放到 SpringMVC 的配置中来完成
测试
添加一个controller:
1 2 3 4 5 6 7
| @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "hello"; } }
|
其他配置
静态资源过滤
静态资源过滤在 SpringMVC 的 XML 中的配置如下:
1
| <mvc:resources mapping="/**" location="/"/>
|
在 Java 配置的 SSM 环境中,如果要配置静态资源过滤,需要让 SpringMVC 的配置继承 WebMvcConfigurationSupport ,进而重写 WebMvcConfigurationSupport 中的方法,如下:
1 2 3 4 5 6 7 8
| @Configuration @ComponentScan(basePackages = "com.cwz") public class SpringMVCConfig extends WebMvcConfigurationSupport { @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/js/**").addResourceLocations("classpath:/"); } }
|
重写 addResourceHandlers 方法,在这个方法中配置静态资源过滤,这里我将静态资源放在 resources 目录下,所以资源位置是 classpath:/
,当然,资源也可以放在 webapp 目录下,此时只需要修改配置中的资源位置即可。如果采用 Java 来配置 SSM 环境,一般来说,可以不必使用 webapp 目录,除非要使用 JSP 做页面模板,否则可以忽略 webapp 目录。
视图解析器
在 XML 文件中,通过如下方式配置视图解析器:
1 2 3 4
| <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
|
如果通过 Java 类配置也是可以的。
首先为我们的项目添加 webapp 目录,webapp 目录中添加一个 jsp 目录,jsp 目录中添加 jsp 文件,然后引入JSP 的依赖:
1 2 3 4 5
| <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency>
|
然后,在配置类中,继续重写方法:
1 2 3 4 5 6 7 8
| @Configuration @ComponentScan(basePackages = "com.cwz") public class SpringMVCConfig extends WebMvcConfigurationSupport { @Override protected void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/jsp/", ".jsp"); } }
|
接下来,在 Controller 中添加控制器即可访问 JSP 页面:
1 2 3 4 5 6 7
| @Controller public class HelloController2 { @GetMapping("/hello2") public String hello() { return "hello"; } }
|
路径映射
有的时候,我们的控制器的作用仅仅只是一个跳转,里边没有任何业务逻辑,像这种情况,可以不用定义方法,可以直接通过路径映射来实现页面访问。如果在 XML
中配置路径映射,如下:
1
| <mvc:view-controller path="/hello" view-name="hello" status-code="200"/>
|
这行配置,表示如果用户访问 /hello
这个路径,则直接将名为 hello
的视图返回给用户,并且响应码为 200
,这个配置就可以替代 Controller
中的方法。
如果在Java类配置中:
1 2 3 4 5 6 7 8
| @Configuration @ComponentScan(basePackages = "com.cwz") public class SpringMVCConfig extends WebMvcConfigurationSupport { @Override protected void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/hello3").setViewName("hello"); } }
|
此时,用户访问 /hello3
接口,就能看到名为 hello
的视图文件。
JSON配置
SpringMVC 可以接收JSON 参数,也可以返回 JSON 参数,这一切依赖于 HttpMessageConverter。
HttpMessageConverter 可以将一个 JSON 字符串转为 对象,也可以将一个对象转为 JSON 字符串,实际上它的底层还是依赖于具体的 JSON 库。
所有的 JSON 库要在 SpringMVC 中自动返回或者接收 JSON,都必须提供和自己相关的 HttpMessageConverter 。
SpringMVC 中,默认提供了 Jackson 和 gson 的 HttpMessageConverter ,分别是:MappingJackson2HttpMessageConverter 和 GsonHttpMessageConverter 。
正因为如此,我们在 SpringMVC 中,如果要使用 JSON ,对于 jackson 和 gson 我们只需要添加依赖,加完依赖就可以直接使用了。具体的配置是在 AllEncompassingFormHttpMessageConverter 类中完成的。
如果开发者使用了 fastjson,那么默认情况下,SpringMVC 并没有提供 fastjson 的 HttpMessageConverter ,这个需要我们自己提供,如果是在 XML 配置中,fastjson 除了加依赖,还要显式配置 HttpMessageConverter,如下:
1 2 3 4 5 6
| <mvc:annotation-driven> <mvc:message-converters> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> </bean> </mvc:message-converters> </mvc:annotation-driven>
|
在 Java 配置的 SSM 中,我们一样也可以添加这样的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Configuration @ComponentScan(basePackages = "com.cwz") public class SpringMVCConfig extends WebMvcConfigurationSupport { @Override protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); converter.setDefaultCharset(Charset.forName("UTF-8")); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setCharset(Charset.forName("UTF-8")); converter.setFastJsonConfig(fastJsonConfig); converters.add(converter); } }
|
然后,就可以在接口中直接返回 JSON 了,此时的 JSON 数据将通过 fastjson 生成。
初始SpringBoot
我们刚开始学习 JavaWeb 的时候,使用 Servlet/JSP 做开发,一个接口搞一个 Servlet ,很头大,后来我们通过隐藏域或者反射等方式,可以减少 Servlet 的创建,但是依然不方便,再后来,我们引入 Struts2/SpringMVC 这一类的框架,来简化我们的开发 ,和 Servlet/JSP 相比,引入框架之后,生产力确实提高了不少,但是用久了,又发现了新的问题,即配置繁琐易出错,要做一个新项目,先搭建环境,环境搭建来搭建去,就是那几行配置,不同的项目,可能就是包不同,其他大部分的配置都是一样的,Java 总是被人诟病配置繁琐代码量巨大,这就是其中一个表现。那么怎么办?Spring Boot 应运而生,Spring Boot 主要提供了如下功能:
- 为所有基于 Spring 的 Java 开发提供方便快捷的入门体验。
- 开箱即用,有自己自定义的配置就是用自己的,没有就使用官方提供的默认的。
- 提供了一系列通用的非功能性的功能,例如嵌入式服务器、安全管理、健康检测等
- 没有代码生成,也不需要XML配置
创建一个 Spring Boot 项目
直接使用IntelliJ IDEA创建或者直接创建一个Maven工程。
在pom.xml中添加如下依赖:
1 2 3 4 5 6 7 8 9 10 11
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
|
添加成功后,再在 java 目录下创建包,包中创建一个名为 App 的启动类,如下:
1 2 3 4 5 6 7 8 9 10 11
| @EnableAutoConfiguration @RestController public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } @GetMapping("/hello") public String hello() { return "hello"; } }
|
@EnableAutoConfiguration 注解表示开启自动化配置。
然后执行这里的 main 方法就可以启动一个 Spring Boot 工程了。
@Configuration注解
@SpringBootApplication是一个组合注解,里面涉及到了@SpringBootConfiguration注解,@SpringBootConfiguration里面又是@Configuration。
@Configuration表示MyConfig类是一个配置类,在配置了中提供bean就可以了。
spring容器启动的时候会默认加载一些后置的处理器,有一个处理器是ConfigurationClassPostProcessor,这个类就是专门处理带有@Configuration注解的类。
有两个for循环,第一个for循环会找到所有带有@Configuration注解的类,把它们保存到configBeanDefs变量中。
第二个for循环实际上是对这个类做了一个增强,相当于替换了原来的class,使用了代理类。
在代理方法调用的时候涉及到BeanMethodInterceptor类的intercept方法,对于已经创建的对象就不再重复创建了。
springboot项目启动类
@SpringBootApplication注解主要包括了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解。
@EnableAutoConfiguration是开启自动化配置,@ComponentScan是包扫描