1.Spring Boot概述

Spring在J2EE开发中是实际意义的标准,但我们在开发Spring时可能会遇到以下问题

  • 大量配置文件的定义
  • 与第三方软件整合的技术问题

Spring每个新版本的推出都以减少配置为主要目标,例如

  • @Componet、@Controller、@Service、@Repository
  • 推出@Configuration、@Bean的Java配置来替代xml配置

在脚本语言和敏捷开发大行其道的时代,J2EE的开发显得尤为笨重,让人误解Java EE开发就是如此。

Spring在提升Java EE开发效率的脚步从未停止,而Spring Boot的推出是具有颠覆和划时代的意义

Spring Boot具有以下特征

  • 遵循”约定大于配置”原则,使用Spring Boot只需要很少的配置,多数可以使用默认配置
  • 项目快速搭建,可无配置整合第三方框架
  • 可完全不使用xml配置,只使用自动配置和Java Config
  • 内嵌Servlet容器(如Tomcat),应用程序可通过jar包运行(java -jar)
  • 监控运行中的应用状态

虽然Spring Boot带来了类似脚本语言的开发效率,但Spring Boot中并没有使用任何新的技术,完全是一个单纯的基于Spring的应用

2.Spring 4.x配置

2.1 @Profile注解

Profile为在不同环境下使用不同的配置提供了支持。

配置方式

  1. 使用@Profile注解类或方法,达到在不同环境下选择实例化不同的Bean
  2. 设置jvm的spring.profiles.active参数来设置配置环境
  3. Web项目设置在Servlet的context parameter中

演示说明

创建实体类

1
2
3
4
5
6
7
@NoArgsConstructor
@AllArgsConstructor
@Data
public class DemoBean {

private String content;
}

创建配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class ProfileConfig {

@Bean("demoBean")
@Profile("dev")
public DemoBean devDemoBean() {
return new DemoBean("from dev profile");
}

@Bean("demoBean")
@Profile("prod")
public DemoBean prodDemoBean() {
return new DemoBean("from prod profile");
}
}

编写测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ProfileTest {

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//set active profile
context.getEnvironment().setActiveProfiles("prod");
context.register(ProfileConfig.class);
context.refresh();
//get demoBean
DemoBean demoBean = context.getBean("demoBean", DemoBean.class);
System.out.println(demoBean.getContent());
}
}

SpringMVC配置

1
2
3
4
5
6
7
8
9
<!--SpringMVC中央控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>prod</param-value>
</init-param>
</servlet>

2.2 条件注解@Conditional

在之前,我们使用@Profile注解来获得不同的Bean,Spring4提供了一种更通用的基于条件的Bean的创建,即使用@Conditional注解

@Conditional根据满足某一特定条件来创建一个特定的Bean。比如,当某个jar包在类路径下时,会自动配置一个或多个Bean。或者只有某个Bean被创建时才会创建另一个Bean

总的来说,就是根据特定条件来控制Bean的创建行为,我们可以利用这个特性进行一些自动的配置

代码演示说明

编写条件类

1
2
3
4
5
6
7
8
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty("os.name").contains("Windows");
}
}
1
2
3
4
5
6
7
8
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty("os.name").contains("Linux");
}
}
1
2
3
4
5
6
7
8
public class MACOSCondition implements Condition {
@Override
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {

return context.getEnvironment().getProperty("os.name").contains("Mac");
}
}

编写配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Configuration
public class ConditionConfig {

@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
return new WindowsListService();
}

@Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService() {
return new LinuxListService();
}

@Bean("listService")
@Conditional(MACOSCondition.class)
public ListService macosListService() {
return new MACOSListService();
}
}

测试类

1
2
3
4
5
6
7
8
9
public class ConditionTest {

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
ListService listService = context.getBean("listService", ListService.class);
String cmd = listService.showListCmd();
System.out.println(cmd);
}
}

3.Spring Boot基础

3.1 快速搭建

  • Maven手动构建

    添加依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    </parent>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    </dependencies>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>

    创建控制器类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @RestController
    public class HelloController {

    @RequestMapping("/hello")
    public String hello() {

    return "Hello SpringBoot";
    }
    }

    创建启动类

    1
    2
    3
    4
    5
    6
    7
    @SpringBootApplication
    public class SpringBootstrap {

    public static void main(String[] args) {
    SpringApplication.run(SpringBootstrap.class, args);
    }
    }

    访问:http://localhost:8080/hello

  • Spring Initializr

    选择Spring Initializr

    配置项目信息

    image-20190702132442071

    勾选Spring Boot组件

    image-20190702132528174

    点击Finish

    image-20190702132558341

3.2 基本配置

  • 入口类和@SpringBootApplication

    Spring Boot通常有一个入口类,入口类里有一个main方法,这个main方法其实就是一个标准的java应用的入口方法。在main方法中使用SpringApplication.run(xxxx.class, args)来启动Spring Boot应用

    @SpringBootApplication是Spring Boot的核心注解,它是一个组合注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {

    /**
    * Exclude specific auto-configuration classes such that they will never be applied.
    * @return the classes to exclude
    */
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};

    @SpringBootApplication注解主要组合了@Configuration、@EnableAutoConfiguration、@ComponentScan。如果不使用@SpringBootApplication注解,则可以在入口类上直接使用@Configuration、@EnableAutoConfiguration、@ComponentScan

    @EnableAutoConfiguration让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置

  • 关闭特定的自动配置

    1
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
  • 定制Banner

    1. 在src/main/resources下新建banner.txt
    2. 通过http://patorjk.com/software/taag生成字符,复制到banner.txt中
    3. 启动Spring Boot应用
  • 关闭Banner

    1
    2
    3
    4
    5
    public static void main(String[] args) {
    SpringApplication app = new SpringApplication(SpringBootstrap.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
    }
  • Spring Boot配置文件

    Spring Boot使用一个全局的配置文件application.propertiesapplication.yml,放置在src/main/resources目录或类路径的**/config**下

    Spring Boot的全局配置文件主要是对一些默认配置的配置进行修改

    简单示例(application.properties)

    1
    2
    server.port=8888
    server.servlet.context-path=/demo

    application.yml

    1
    2
    3
    4
    server:
    port: 8889
    servlet:
    context-path: /hello
  • starter pom

    Spring Boot提供了简化企业级开发绝大多数数场景的starter pom,只要使用了应用场景所需的starter pom,则不需进行额外相关配置,就可以得到Spring Boot为我们提供的自动配置的Bean

    https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/using-boot-build-systems.html#using-boot-starter

  • 使用xml配置

    Spring Boot提倡零配置,即无xml配置。但在实际项目中,可能会有一些特殊要求必须使用xml配置,这时可以通过Spring Boot提供的@ImportResource注解来加载xml配置

    1
    @ImportResource({"classpath:some-context.xml", "classpath:another-context.xml"})

3.3 外部配置

Spring Boot允许使用properties文件、yml文件或者命令行参数来作为外部配置

  • 命令行参数配置

    1
    java -jar xx.jar --server.port=9090
  • 常规属性配置(application.properties)

    在常规的Spring环境下,通常需要使用@PropertySource指明properties文件的位置,再通过@Value注解注入值。在Spring Boot中,只需要在application.properties定义属性,直接使用@Value注解注入即可

    1
    2
    3
    book.author=mike
    book.name=spring boot
    book.version=v1.0

    属性注入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @RestController
    public class HelloController {

    @Value("${book.author}")
    private String bookAuthor;
    @Value("${book.name}")
    private String bookName;
    @Value("${book.version}")
    private String bookVersion;

    @RequestMapping("/hello")
    public String hello() {

    return "bookAuthor: " + bookAuthor + " bookName: " + bookName + " bookVersion: " + bookVersion;
    }
    }
  • 基于类型安全的配置(application.properties)

    使用@Value注解在对多个属性进行注入时,显得格外麻烦,通过需要配置多次注入。

    Spring Boot提供了基于类型安全的配置方式,通过@ConfigurationProperties注解将properties属性和一个Bean及其属性关联,从而实现安全的配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @Data
    @Component
    @ConfigurationProperties(prefix = "book")
    public class BookSetting {

    private String author;
    private String name;
    private String version;

    @Override
    public String toString() {
    return "BookSetting{" +
    "author='" + author + '\'' +
    ", name='" + name + '\'' +
    ", version='" + version + '\'' +
    '}';
    }
    }

    Bean注入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @RestController
    public class HelloController {

    @Autowired
    private BookSetting bookSetting;

    @RequestMapping("/hello")
    public String hello() {

    return "bookAuthor: " + bookSetting;
    }
    }

3.4 日志配置

Spring Boot支持Java Util Logging、Log4j、Log4j2以及LogBack作为日志框架

无论是用哪一种框架,Spring Boot已经为当前日志框架的控制台输出及文件输出做好的配置

默认情况下,Spring Boot使用LogBack作为日志框架

日志文件输出路径

1
logging.file=/xxx/xx/xx/xxx.log

日志输出级别

1
2
logging.level.root=INFO
logging.level.org.springframework.web=DEBUG

3.5 Profile配置

Profile是Spring用来针对不同环境的不同配置提供支持,全局的Profile配置使用application-{profile}.properties(如application-prod.properties)

通过在application.properties中设置spring.profiles.active=prod来指定活动的Profile

例如

application-prod.proerties

1
server.port=8888

application-dev.proerties

1
server.port=8080

application.proerties

1
spring.profiles.active=prod

3.6 yaml文件

在Spring Boot中,推荐使用properties或者yaml文件来完成配置,但是对于较复杂的数据结构来说,yaml又远远优于properties

properties vs yaml

1
2
3
4
5
6
7
#properties
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
1
2
3
4
5
6
7
8
9
10
11
12
#yaml
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
my:
servers:
- dev.bar.com
- foo.bar.com

可以直观的看到,yaml使用冒号加缩进的方式代表层级(属性)关系,使用短横杠(-)代表数组元素。

yaml中的三种格式

  • 常量
  • 对象
  • 数组
1
2
3
4
5
6
7
8
9
10
11
12
#常量
pi: 3.1415
hasChild: true
name: "Mike"
#对象
server:
port: 8888
address: 0.0.0.0
#数组
fruits:
- apple
- orange

基本格式要求

  • yaml大小写敏感
  • 使用缩进代表层级关系
  • 缩进只能使用空格,不能使用TAB,不要求空格个数,只需要相同层级左对齐(一般2个或4个空格)

特殊符号

  • — 表示一个文档的开始,用来分割不同的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    server:
    port: 8080
    spring:
    profiles:
    active: prod
    ---
    spring:
    profiles: dev
    server:
    port: 8888
    ---
    spring:
    profiles: prod
    server:
    port: 8088
  • … 和—配合使用,在一个配置文件中代表一个文件的结束

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    server:
    port: 8080
    spring:
    profiles:
    active: prod
    ---
    spring:
    profiles: dev
    server:
    port: 8888
    ...
    ---
    spring:
    profiles: prod
    server:
    port: 8088
    ...

4.Spring BootWeb开发

Spring Boot提供了spring-boot-starter-web为web开发提供支持,而且还提供了嵌入的Tomcat和Spring MVC的依赖

4.1 Thymeleaf模板引擎

Thymeleaf是一个Java类库,它是一个能够处理html/css/javascript/css/文本的模板引擎,可以作为MVC三层中的View层

Thymeleaf还提供了额外的模块与SpringMVC集成,所以我们可以使用Thymeleaf完全替代JSP

  1. 引入Thymeleaf

    1
    <html xmlns:th="http://www.thymeleaf.org">

    通过xmlns:th="http://www.thymeleaf.org"命名空间,当前页面转换为动态视图,需要进行动态处理的元素将使用th:为前缀

  2. 引入资源文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" th:src="@{css/bootstrap-theme.min.css}">
    </head>
    <body>

    <script th:src="@{js/jquery.min.js}"></script>
    </body>
    </html>

    通过@{}引用Web静态资源

  3. 访问model中的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" th:src="@{css/bootstrap.min.css}">
    </head>

    <body>
    <p th:text="${user.name}"></p>
    <script th:src="@{js/jquery.min.js}"></script>
    </body>
    </html>
  4. model中的数据迭代

    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
    28
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" th:src="@{css/bootstrap.min.css}">
    </head>
    <body>
    <table>
    <tr>
    <th>编号</th>
    <th>姓名</th>
    <th>年龄</th>
    <th>操作</th>
    </tr>
    <tr th:each="user:${userList}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
    <td>
    <a href="#">编辑</a>|
    <a href="#">编辑</a>|<a th:href="'deleteById/' + ${user.id}">删除</a>
    </td>
    </tr>
    </table>
    <script th:src="@{js/jquery.min.js}"></script>
    </body>
    </html>
  5. 条件判断

    1
    2
    3
    4
    5
    6
    7
    8
    <tr th:each="user:${userList}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
    <td th:if="${user.age > 20}">
    <a href="#">编辑</a>|<a th:href="'deleteById/' + ${user.id}">删除</a>
    </td>
    </tr>

4.2 Thymeleaf与SpringMVC集成

在SpringMVC中,若需要集成一个模板引擎,需要定义一个新的ViewResoResolver

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
28
29
30
31
32
33
@Configuration
@EnableWebMvc
@ComponentScan("com.web.controller")
public class WebConfig extends WebMvcConfigurerAdapter {

//配置Thymeleaf视图解析器
@Bean
public ViewResolver viewResolver(TemplateEngine templateEngine){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setCharacterEncoding("utf-8");
return viewResolver;
}

//创建模板引擎
@Bean
public TemplateEngine templateEngine(ITemplateResolver templateResolver){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}

//创建Thymeleaf模板解析器
@Bean
public ITemplateResolver templateResolver(){
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCacheable(false);
resolver.setCharacterEncoding("utf-8");
return resolver;
}

4.3 SpringBoot的Thymeleaf支持

Spring Boot通过org.springframework.boot.autoconfigure.thymeleaf包对Thymeleaf进行了自动配置

添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

根据默认原则,css、js、image等静态文件应放在src/main/resources/static下,页面应该放在src/main/resources/templates

4.4 静态资源配置

Spring Boot定义了一下静态资源的自动配置

  • 类路径文件

    把类路径下的/static、/public、/resources和/META-INF/resources/文件夹下的静态文件直接映射为/**

    可以通过http://localhost:8080/**访问

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
    public class ResourceProperties {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/" };

    /**
    * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
    * /resources/, /static/, /public/].
    */
    private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
  • webjar

    webjar就是将常用的脚本框架封装在jar包中,访问http://www.webjars.com

  • 静态首页

    • classpath:/META_INF/resources/index.html

    • classpath:/resources/index.html

    • classpath:/static/index.html

    • classpath:/public/index.html

    访问http://localhost:8080/时,会直接映射

4.5 接管Spring Boot的Web配置

Spring Boot的自动配置符合我们大多数的需求,在即需要保留Spring Boot提供的便利,有需要增加自己额外的配置,可以定义一个配置类并继承WebMvcConfigurerAdapter,无需使用@EnableEnableWebMvc注解

1
2
3
4
5
6
7
8
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/xx").setViewName("/xxx");
}
}

4.6 注册Servlet、Filter、Listener

当使用嵌入式的Servlet服务器(Tomcat、Jetty)时,我们通过将Servlet、Filter和Listener声明为Spring Bean来达到注册的效果,或者注册ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean

直接注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/xx").setViewName("/xxx");
}


@Bean
public MyServlet myServlet() {
return new MyServlet();
}

@Bean
public MyFilter myFilter() {
return new MyFilter();
}

@Bean
public MyListener yyListener() {
return new MyListener();
}
}

通过RegistrationBean注册

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
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/xx").setViewName("/xxx");
}

@Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new MyServlet(), "/myServlet");
}

@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new MyFilter());
filterRegistrationBean.setOrder(2);

return filterRegistrationBean;
}

@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
return new ServletListenerRegistrationBean<MyListener>(new MyListener());
}
}

4.7 Tomcat配置

关于Tomcat的所有属性都在org.springframework.boot.autoconfigure.web.ServerProperties类中

我们只需在application.properties中配置即可

1
2
3
4
5
6
7
8
9
10
11
12
#配置tomcat端口
server.port=8888
#配置session超时时间
server.servlet.session.timeout=60
#配置访问路径,默认为/
server.servlet.context-path=/springboot
#配置Tomcat编码,默认UTF-8
server.tomcat.uri-encoding=UTF-8
#配置Tomcat是否开启压缩,默认关闭
server.compression.enabled=true
#错误处理
server.error.path=/error

4.8 替换Tomcat

在pom.xml中,将spring-boot-starter-web的依赖由spring-boot-starter-tomcat替换为spring-boot-starter-jetty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

5.Spring Boot数据访问

5.1 添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

5.2 配置事务管理

application.properties

1
2
3
4
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/user_db
jdbc.user=root
jdbc.password=111111

jdbc配置类

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
28
@Data
@Configuration
@PropertySource("classpath:jdbc.properties")
@ConfigurationProperties(prefix = "jdbc")
public class JdbcConfig {

private String driver;
private String url;
private String user;
private String password;

@Bean
public DataSource createDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(user);
druidDataSource.setPassword(password);

return druidDataSource;
}

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}

}

5.3 集成MyBatis

添加依赖

1
2
3
4
5
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>

创建接口与实体类

1
2
3
public interface UserDao {
List<User> findAll();
}

resources/mapper下创建Mapper文件

1
2
3
4
5
6
7
8
9
10
11
<?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.web.dao.UserDao">

<select id="findAll" resultType="user">
select * from t_user
</select>

</mapper>

application.properties

1
2
mybatis.mapper-locations=classpath:mapper/**.xml
mybatis.type-aliases-package=com.web.domain

启动类

1
2
3
4
5
6
7
@SpringBootApplication
@MapperScan("com.web.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

6.Spring Boot单元测试

6.1 Spring Boot测试脚手架

添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>

简单测试

1
2
3
4
5
6
7
8
9
10
11
12
13
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {

@Autowired
private UserService userService;

@Test
public void testUserService() {
List<User> list = userService.findAll();
System.out.println(list);
}
}

7.Rest集成

Rest配置类

1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class RestConfig {

@Autowired
private RestTemplateBuilder restTemplateBuilder;

@Bean
public RestTemplate restTemplate() {
return restTemplateBuilder.build();
}
}

发送rest请求

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
public class HelloController {

@Autowired
private RestTemplate restTemplate;

@RequestMapping(value = "/hello", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
public User hello() {
User user = restTemplate.getForObject("http://localhost:8888/api/users", User.class);
return user;
}
}

8.Redis集成

添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>

application.proerties

1
2
spring.redis.host=localhost
spring.redis.port=6379

自动装配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
public class HelloController {
@Autowired
private StringRedisTemplate redisTemplate;

@RequestMapping(value = "/hello", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
public void hello() {
//set key
redisTemplate.opsForValue().set("k1", "v1");
//get key
redisTemplate.opsForValue().get("k2");
//set list
redisTemplate.opsForList().leftPush("mylist","a","b");
//get list
redisTemplate.opsForList().range("mylist", 0, -1);
}
}

9.Spring Session

Spring Boot应用通常会部署在多个Web服务器上同时提供服务,这样做的好处

  • 单个引用宕机不会停止服务,升级应用可逐个升级而不必停掉服务
  • 提高了应用整体的吞吐量

这种部署方式称为水平扩展,前端通过Nginx提供反向代理,会话管理可以通过Spring Session,使用Redis来存放Session

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>

application.properties

1
2
3
spring.session.store-type=redis
spring.redis.host=localhost
spring.redis.port=6379

Redis配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
@EnableRedisHttpSession
public class RestConfig {

@Autowired
private RestTemplateBuilder restTemplateBuilder;

@Bean
public RestTemplate restTemplate() {
return restTemplateBuilder.build();
}


@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory();
return connection;
}

}

10.Spring Boot监控

J2EE规范中由JMX来监控管理应用,Spring Boot也提供了Actuator功能来完成类似的监控,通过Http,JMX,甚至远程脚本(SSH)来查看Spring Boot应用的配置、各种指标、健康程度等

它能查看和监控以下信息

  • Spring Boot的配置信息
  • Spring Boot配置的Bean信息
  • 最近请求的Http信息
  • 数据源、NoSQL等数据状态
  • 在线查看日志内容,在线日志配置修改
  • 所有@RequestMapping注解的URL路径
  • 自动装配信息汇总
  • 打印虚拟机线程栈
  • Dump内存
  • 应用的各种指标汇总
  • 自定义监控指标

添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.properties

1
2
3
4
5
6
#开启全部
management.endpoints.web.exposure.include=*
#开启某个
management.endpoints.web.exposure.include=metrics
#关闭某个
management.endpoints.web.exposure.exclude=metrics

通常不建议全部开启,因为不安全

访问:http://localhost:8080/actuator/env

获得配置信息

访问:http://localhost:8080/actuator/beans

监控项目Spring中的beans

访问:http://localhost:8080/actuator/metrics

查看应用基本指标列表

访问:http://localhost:8080/actuator/mappings

显示所有的@RequestMapping路径