跟着官网学习Spring Boot
笔者使用的是1.5.10版本的Spring Boot。
简介
-
什么是Spring Boot:
Spring Boot是由Pivotal团队提供的开源框架,用于简化Spring应用的初始搭建及开发过程。该框架使用继承starter(约定大于配置)的方式进行配置,从而是开发人员不再需要定义样板话的配置,致力于蓬勃发展的快熟应用开发领域。
从根本上讲,Spring Boot又不是一个框架,而是一些库的集合,maven或gradle项目只需要导入相应依赖即可使用Spring Boot,且无需自行管理这些库的版本。 -
Spring Boot的功能:
内置tomcat,避免不同tomcat版本而出现异常,且构建的fat Jar包通过Java -jar就可以直接运行。
支持全注解。
支持热部署(eclips),spring-boot-devtools。
依赖了各种xml的配置,因此创建maven等项目时不再需要各种xml配置,只需要添加依赖即可。
Spring Boot使编码、配置、部署、监控等都变得更加简单。
例如:使用maven时,只需简单的在pom中包含spring-boot-starter-web即引入了Spring MVC和Tomcat的依赖。
下面是Spring Boot在 org.springframework.boot 组下提供的一些Starters:
Spring Boot入门
-
环境要求:
开发环境 JDK1.7+;
项目管理工具 maven 3.2+;
开发工具 eclipse(idea在热部署等方面存在些许bug)。 -
使用eclipse创建maven项目:
创建maven项目时需要勾选create a simple project; -
导入Spring Boot依赖:
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>springboot_parent</groupId>
<artifactId>springboot_parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- Inherit defaults from Spring Boot springboot继承的父类-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<properties>
<!-- 其父类jdk为1.6,在此指定当前使用版本 -->
<java.version>1.8</java.version>
</properties>
<!-- Add typical dependencies for a web application -->
<dependencies>
<!-- web项目 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- Package as an executable jar 打包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 编写启动类 main方法:
@SpringBootApplication
//该注解相当于配置的扫描包,服务启动时,spring会自动扫描有该注解的类所在的包。
public class StartApp {
public static void main(String[] args) {
SpringApplication.run(StartApp.class, args);
}
}
建议把启动类放到外层包。
- 测试:
@Controller
public class Example {
@RequestMapping("/")
String home() {
return "Hello World!";
}
}
- 热部署:
Spring Boot可以通过添加spring-boot-devtools依赖实现项目的热部署:
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
spring-boot-devtools 是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去。原理是在发现代码有更改之后,重新启动应用,但是速度比手动停止后再启动还要更快,其深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为 restart ClassLoader,更改代码时,原来的restart ClassLoader被丢弃,再新建一个restart ClassLoader,由于需要加载的类较少,所以实现了较快的重启时间,从而提高开发效率。
Spring Boot Web
-
跳转JSP页面的步骤:
创建maven项目
引入对应依赖
配置application.yml(application.properties),以支持jsp
编写controller跳转页面
创建jsp页面
创建启动类 -
创建项目,导入对应依赖:
<!--必须有才能编译jsp -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
- 编写application.yml配置文件:
server:
port: 80
spring:
mvc:
view:
prefix: /WEB-INF/view/
suffix: .jsp
name: lis
age: 15
- 测试代码:
@Controller
public class HelloController {
@Value("${name}")
String name;
@RequestMapping("/hello")
public String helloJsp(HttpServletRequest request){
request.setAttribute("name", name);
System.out.println(name);
return "hello";
}
}
- 创建Jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
hello ${name}你好!
</body>
</html>
注意:jsp页面放置位置必须与yml文件中的配置对应。
- 获取Json数据:
@Controller
public class HelloController {
@Value("${name}")
String name;
@RequestMapping("/json")
@ResponseBody
public Object json(){
Map<String,Object> map = new HashMap<>();
map.put("name", "李四");
map.put("pwd", "123");
return map;
}
}
Spring Boot-JDBC
- 引入对JDBC的依赖:
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
- 引入测试依赖:
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
- 数据库相应配置yml:
datasource:
driverClassName: com.mysql.jdbc.Driver
url : jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
username : root
password : ******
- domain层:
package com.lis.domain;
public class User {
private Integer id;
private String name;
private String pwd;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
- dao层:
public interface IUserDao {
public List<User> findAll();
}
@Repository
public class UserDaoImpl implements IUserDao{
@Autowired
JdbcTemplate template;
@Override
public List<User> findAll() {
//查询语句
String sql = "select * from t_user";
//用于封装查询结果,类似于resultMapper
RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
List<User> list = template.query(sql , rowMapper);
return list;
}
}
- 测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=StartApp.class)
public class DaoTest {
@Autowired
IUserDao userDao;
@Test
public void testFindAll() throws Exception {
List<User> list = userDao.findAll();
System.out.println(list.size());//20
}
}
此处为了方便,直接测试dao层,其他层及方法以此类推。
Spring Boot-JPA
-
Spring data jpa:
可以极大的简化JPA的写法,几乎再不用写实现的情况下,实现对数据的访问和操作。详见:Spring data jpa简介。 -
引入相应依赖:
<!-- JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
- 沿用JDBC的yml配置:
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url : jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
username : root
password : lis5627
注:测试等代码详见JDBC,基本类似,仅JDBC与JPA的区别,在此就不再赘述。
Spring Boot-Mybatis
- 创建springboot_mybatis maven项目
- 导入对应依赖:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>springboot_jpa</artifactId>
<groupId>springboot_jpa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot_mybatis</artifactId>
<dependencies>
<!-- spring-boot mybatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- spring boot mybatis 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
</project>
- 创建实体类:
package com.lis.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "t_user")
public class User implements Serializable {
@Id
@GeneratedValue
private Integer id;
private String name;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
- 创建dao接口:
package com.lis.dao;
import com.lis.domain.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface IUserDao {
//查询所有,注解模式
@Select("select * from t_user")
public List<User> queryAll();
//查询一条数据,注解模式
@Select("select * from t_user where id = #{id}")
public User queryById(Long id);
//添加一条数据,使用映射文件
public void saveUser(User user);
}
- 创建mapper映射文件:
<?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="com.lis.dao.IUserDao">
<insert id="saveUser">
insert into t_user(name,password) values (#{name},#{password})
</insert>
</mapper>
- yml配置文件:
# Mybatis配置
mybatis:
typeAliasesPackage: com.lis.domain
mapperLocations: classpath:com/lis/dao/mapper/*.xml
configLocation: classpath:mybatisConfig.xml
注意:如果要在idea中使用映射文件,需要在pom.xml中添加下面的依赖:
<build>
<!-- mapper.xml 扫描 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
- service层:
package com.lis.service;
import com.github.pagehelper.PageInfo;
import com.lis.domain.User;
import java.util.List;
public interface UserService {
//查询所有
public List<User> queryAll();
//查询一条数据
public User queryById(Long id);
//添加一条数据
public void saveUser(User user);
//分页查询
public PageInfo<User> queryByPage(Integer pageNum, Integer pageSize);
}
实现层:
package com.lis.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lis.dao.IUserDao;
import com.lis.domain.User;
import com.lis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
IUserDao userDao;
@Override
@Transactional
public void updateUser(User user) {
userDao.updateUser(user);
}
@Override
@Transactional
public void deleteById(Long id) {
userDao.deleteById(id);
}
@Override
public PageInfo<User> queryByPage(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> list = userDao.queryAll();
return new PageInfo<>(list);
}
@Override
@Transactional
public void saveUser(User user) {
userDao.saveUser(user);
}
@Override
public List<User> queryAll() {
return userDao.queryAll();
}
@Override
public User queryById(Long id) {
return userDao.queryById(id);
}
}
- 测试:
package serviceTest;
import com.github.pagehelper.PageInfo;
import com.lis.RunApp;
import com.lis.domain.User;
import com.lis.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = RunApp.class)
public class ServiceTest {
@Autowired
private UserService userService;
@Test
public void testQueryAll() throws Exception{
System.out.println(userService.queryAll().size());
}
@Test
public void testQueryById() throws Exception{
System.out.println(userService.queryById(2L));
}
@Test
public void testSaveUser() throws Exception{
User user = new User();
user.setName("李四");
user.setPassword("123");
userService.saveUser(user);
}
@Test
public void testQueryByPage() throws Exception{
PageInfo<User> page = userService.queryByPage(1, 5);
for (User user : page.getList()) {
System.out.println(user);
}
}
}
总结
使用spring boot可以非常方便、快速搭建项目,使我们不用关心框架之间的兼容性,适用版本等各种问题,我们想使用任何东西,仅仅添加一个配置就可以,所以使用sping boot非常适合构建微服务。