一、Spring Boot 概述
1. 什么是 Spring Boot
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。简单的来说 Spring Boot 这个项目整合目前很多的流行的第三方框架,并且做了一系列的默认配置,我们无需在进行手动配置,直接拿过来直接使用! 接下来我们比较一下Spring mvc和 Spring Boot的开发过程
Spring mvc
-
导入 spring mvc 的相关依赖包
-
在 web.xml 文件中配置 Spring mvc 的前端控制器
-
创建一个 spring mvc 的配置文件
-
在 spring mvc 的配置文件中进行相关配置
1)配置注解扫描路径 2)配置处理器映射器 3)配置处理器适配器 4)配置视图解析器
-
开发 Controller
Spring Boot
-
导入相关的依赖包
-
开发 Controller
单单从开发步骤上讲都比我们的原始开发少了很多,其中的配置部分 Spring Boot 帮我们完成了,不需要 我们在进行配置,当然如果我们想更改 Spring Boot 的默认配置也是可以的.极大的简化了我们的开发.
2. Spring Boot 的核心功能
- 独立运行的 spring 项目: Spring Boot 可以以 jar 包形式直接运行,如 java -jar xxx.jar 优点是:节省服务器资源
- 内嵌 servlet 容器: Spring Boot 可以选择内嵌 Tomcat,Jetty,这样我们无须以 war 包形式部署项目。
- 提供 starter 简化 Maven 配置: 在 Spring Boot 项目中为我们提供了很多的 spring-boot-starter-xxx 的项目(我们把这个依赖可以称之为起步依赖,我们导入指定的这些项目的坐标,就会自动导入和该模块相关的依赖包:例如我们后期再使用 Spring Boot 进行 web 开发我们就需要导入 spring-boot-starter-web 这个项目的依赖,导入这个依赖以后!那么Spring Boot 就会自动导入 web 开发所需要的其他的依赖包
- 自动配置 spring: Spring Boot 会根据在类路径中的 jar 包,类,为 jar 包里的类自动配置 Bean,这样会极大减少我们要使用的配置。当然 Spring Boot 只考虑了大部分开发场景,并不是所有的场景,如果在实际的开发中我们需要自动配置 Bean,而 Spring Boot 不能满足,则可以自定义自动配置。
- 准生产的应用监控: Spring Boot 提供基于 http,ssh,telnet 对运行时的项目进行监控。
- 无代码生成和 xml 配置: Spring Boot 大量使用 spring4.x 提供的注解新特性来实现无代码生成和 xml 配置。spring4.x 提倡使用 Java配置和注解配置组合,而 Spring Boot 不需要任何 xml 配置即可实现 spring 的所有配置。
3. Spring Boot 的优点和缺点
3.1 优点
- 快速构建项目
- 对主流框架无缝集成
- 项目可以独立运行,无需依赖外部 servlet 容器
- 提供运行时的应用监控
- 极大提高了开发,部署效率
3.2 缺点
- 资料相对比较少
- 版本迭代较快
二、Spring Boot 入门案例
1. 新建maven项目
创建后项目结构如下:
2. 新建相关文件夹与包
main/java下新建包cn.itcast.start
resources文件夹下新建相关内容
3. pom.xml文件添加maven依赖
<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>cn.itcast</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--Spring Boot 项目默认的编译版本是 1.6,如果我们想使用其他的编译版本我们就需要在 pom.xml 文件中定义一个变量-->
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 加入web开发的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- maven的编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 没有该配置,devtools 不生效 -->
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
4. 开发 Controller
在cn.itcast.start.controller包下创建测试UserController.java
//@RestController注解相当于@ResponseBody + @Controller合在一起的作用
@RestController
public class UserController {
@RequestMapping("info")
public User hello(){
User user = new User();
user.setUsername("张三丰");
user.setAddress("揭阳市");
return user;
}
}
5. 开发启动类HelloSpringBootApplication.java
package cn.itcast.start;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
//主Application类(加了SpringBootApplication的类),一定要放在代码的最外层,即Application.class与包同一级别
//这样可以保证在装配Bean的时候从Application所在的文件下从上向下扫描时,所有的类都会被装配进项目。
// 而如果写在某个包里,Application.class扫描时扫描不到其他class,因此springboot启动的时候没有报错,但是没办法进行访问
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
//入口运行类
SpringApplication.run(MySpringBootApplication.class, args);
}
}
创建后项目结构如下:
温馨提示:
- MySpringBootApplication启动类一定要放在代码的最外层,即Application.class与包同一级别,这样可以保证在装配Bean的时候从Application所在的文件下从上向下扫描时,所有的类都会被装配进项目。如果写在某个包里,Application.class扫描时扫描不到其他class,因此springboot启动的时候没有报错,但是没办法进行访问。
- @RestController注解相当于@ResponseBody + @Controller合在一起的作用
- @Controller注解如果没指定访问的url,那么该类下面的@RequestMapping方法不能出现重名(整个项目都不可以出现)
6. 运行项目并访问
浏览器进行访问
三、Spring Boot核心功能代码实战
1. 无 xml 配置的实现
自从 spring3.0 以后 spring 提供了很多的注解来替代 xml 文件的配置.最为核心的是下面的两个注解:
- @Configuration 标注该类是一个配置类.类似于我们定义的 applicationContext.xml
- @Bean 类似于我们在之前的 spring 配置文件中配置的
有了上面的两个注解我们就可以使用编码的方式来完成 spring 的相关配置,接下来我们就来使用 java 编码的方式来完成 spring 的配置
1.1 新建HelloService.java
在cn.itcast.start.service下新建HelloService.java类
package cn.itcast.start.service;
public interface HelloService {
public String sayHello();
}
1.2 新建HelloServiceImpl.java
cn.itcast.start.service.impl包下新建HelloServiceImpl.java
package cn.itcast.start.service.impl;
import cn.itcast.start.service.HelloService;
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello() {
return "Hello JavaConfig";
}
}
创建后项目文件结构如下:
1.3 编写配置类
cn.itcast.start.config包下新建JavaConfigTest.java类
package cn.itcast.start.config;
import cn.itcast.start.service.HelloService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigTest {
public static void main(String[] args) {
// 通过AnnotationConfigApplicationContext这个类获取Spring容器
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext(ApplicationConfiguration.class) ;
HelloService helloService = applicationContext.getBean(HelloService.class) ;
String result = helloService.sayHello() ;
System.out.println(result);
}
}
1.4 运行JavaConfigTest.java
这个时候我们应该就明白了 Spring Boot 项目之所以能做到不需要 xml 文件,是因为它使用了这两个注解替换了之前了 xml 文件的配置。
2. 静态资源的访问
在我们 web 开发中,存在很多的一些 css , js , 图片等等一些静态的资源文件!那么我们应该把这些静态资源存储在什么目录下呢?Spring Boot 项目要求我们将这个静态资源文件存储到 resources 目录下的 static 目录中; 当然这个配置是可以进行更改的,但是不建议更改!在进行访问的时候我们不需要添加上 static 文件目录,Spring Boot 会自动在 static 目录中查找对应的资源文件.
我们新建在resouces下的static文件夹就是用于存放静态资源的,静态资源的实战我们会在下面的模板引擎(freemarker)进行介绍
3. 模板引擎(freemarker)
Spring Boot 项目建议我们使用模板引擎来进行页面视图的渲染,而不建议我们使用 jsp! 因此内嵌的 tomcat 也没有提供 jsp 页面的支持.Spring Boot 提供了大量的模板引擎,包含: Freemarker , Groovy , Thymeleaf , Velocity 和 Mustache. 本次我们就来讲解一下 Spring Boot继承 freemarker 作为页面视图!
3.1 pom.xml添加依赖
<!--添加模板引擎(freemarker)依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
3.2 添加静态资源文件
将项目源码与资料下载中的资源文件复制进去static文件夹下
3.3 添加模板引擎
Spring Boot 项目为我们提供了一个 templates 目录专门用来存储模板文件的. 因此我们需要将指定的模板文件放在该目录下! 模板文件的后缀名默认是 ftl.
3.4 新建访问Controller类
cn.itcast.start.controller包下新建JdController.java
package cn.itcast.start.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//当使用Controller或RestController时,没指定访问的RequestMapping,那么所有的RequestMapping不能出现同名,否则启动会报错
@Controller
public class JdController {
/**
* 需求:返回jd首页
*/
@RequestMapping("list")
public String jdList(){
return "index";
}
}
3.5 运行项目并访问
4. 文件上传
4.1 新增模板文件
templates文件夹下新建模板文件file-upload.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户添加</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/bootstrap-theme.min.css" />
<link rel="stylesheet" href="css/bootstrap.min.css" />
<script type="text/javascript" src="js/jquery-1.11.3.min.js" ></script>
<script type="text/javascript" src="js/bootstrap.min.js" ></script>
</head>
<body class="container">
<center>
<h1>文件上传表单</h1>
</center>
<form role="form" action="/fileUpload" enctype="multipart/form-data" method="post">
<div class="form-group">
<label for="inputfile">文件输入</label>
<input type="file" id="inputfile" name="uploadFile">
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
</body>
</html>
4.2 新建上传文件 Controller
cn.itcast.start.controller包下新建UploadController.java
package cn.itcast.start.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
@Controller
public class UploadController {
/**
* 需求:返回文件上传页面
*/
@RequestMapping("file")
public String jdList(){
return "file-Upload";
}
@RequestMapping(value = "/fileUpload")
@ResponseBody
public String fileUpload(MultipartFile uploadFile) {
try {
File file = new File("D:\\images\\" + uploadFile.getOriginalFilename()) ;
uploadFile.transferTo(file);
} catch (Exception e) {
e.printStackTrace();
}
return "success" ;
}
}
4.3 运行项目并访问
6. 拦截器
拦截器对使用 Spring mvc、Struts 的开发人员来说特别熟悉,因为你只要想去做好一个项目必然会用到它。拦截器在我们平时的项目中用处有很多,如:日志记录、用户登录状态拦截、安全拦截等等。而 Spring Boot 内部集成的是 Spring mvc 控制框架,所以使用起来跟SpringMVC 没有区别,只是在配置上有点不同。
下面演示拦截文件上传接口,并直接跳转到商城首页
6.1 编写拦截器
cn.itcast.start.interceptor包下新建CheckUserLoginInterceptor.java
package cn.itcast.start.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CheckUserLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object
handler) throws Exception {
response.sendRedirect("/list");
return false ;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object
handler, Exception ex) throws Exception {
}
}
6.2 配置拦截器
cn.itcast.start.config包下新建InterceptorConfig.java
package cn.itcast.start.config;
import cn.itcast.start.interceptor.CheckUserLoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CheckUserLoginInterceptor()).addPathPatterns("/file") ;
}
}
6.3 运行项目并访问
7. 整合mybatis
7.1 新建数据库
我已经准备好相应的.sql文件在项目源码与资料下载中,请直接使用Navicat for MySQL工具进行导入,数据库名为springboot_test,具体字段如下:
7.2 pom.xml文件添加maven依赖
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--阿里巴巴数据连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.28</version>
</dependency>
7.3 添加配置文件
application.properties文件下添加以下内容:
#spring集成Mybatis环境
mybatis.type-aliases-package=cn.itcast.start.domain
#加载Mybatis配置文件
mybatis.mapper-locations = classpath:mapper/*Mapper.xml
mybatis.config-location = classpath:mapper/config/sqlMapConfig.xml
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/springboot_test?useUnicode=true&useSSL=true
spring.datasource.username = root
spring.datasource.password = 147258qq
mapper文件夹下新建UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.itcast.start.mapper.UserMapper">
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
创建后项目结构如下:
7.4 新建相关代码
cn.itcast.start.domain包下新建实体类User.java
package cn.itcast.start.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
cn.itcast.start.mapper包下新建UserMapper.java
package cn.itcast.start.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import cn.itcast.start.domain.User;
@Mapper
public interface UserMapper {
public List<User> findAll();
}
cn.itcast.start.service包下新建UserService.java
package cn.itcast.start.service;
import java.util.List;
import java.util.Map;
import cn.itcast.start.domain.User;
public interface UserService {
/**
* 根据接口查询所用的用户
*/
}
cn.itcast.start.service.impl包下新建UserServiceImpl.java
package cn.itcast.start.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;
import cn.itcast.start.domain.User;
import cn.itcast.start.mapper.UserMapper;
import cn.itcast.start.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public List<User> findAllUser() {
List<User> list = userMapper.findAll();
return list;
}
}
cn.itcast.start.controller包下新建UserController.java
package cn.itcast.start.controller;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.itcast.start.domain.User;
import cn.itcast.start.service.UserService;
//@RestController注解相当于@ResponseBody + @Controller合在一起的作用
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("info")
public User hello(){
User user = new User();
user.setUsername("张三丰");
user.setAddress("揭阳市");
return user;
}
@RequestMapping("list2")
public List<User> list2(){
List<User> list = userService.findAllUser();
return list;
}
}
7.5 运行项目并访问
8. 项目热部署(开发时使用)
在进行项目开发阶段,我们需要频繁的修改代码,来进行项目的测试!每一次进行项目代码修改的时候,我们都需要进行项目重新启动,这样新添加的代码才可以生效!这种做法比较麻烦.我们就可以使用 Spring Boot 为我们提供的: spring-boot-devtools,来进行项目的热部署! 我们只需要引入对应的依赖包即可!
8.1 pom.xml文件添加相关配置
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 没有该配置,devtools 不生效 -->
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
8.2 application.properties文件添加配置
#热部署生效
spring.devtools.restart.enabled:true
#设置重启的目录
spring.devtools.restart.additional-paths:src/main/java
#classpath目录下的WEB-INF文件夹内容修改不重启
spring.devtools.restart.exclude:WEB-INF/**
8.3 idea修改配置
这样配置在myeclipse中已经可以实现热启动,但是在idea中配置好无效,下面需要修改idea中的两个配置
- setting –> compiler ,将 Build project automatically 勾选上
- alt + shift + a 搜索 registry 选第一个,弹出框后下拉找到compiler.automake.allow.when.app.running 勾选上即可。
- 重启idea