一、springboot简介
1.1什么是springboot?
Spring Boot 是所有基于 Spring Framework 5.0 开发的项目。
Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序,并且尽可能减少你的配置文件。
Spring Boot内部集成各类应用库(jar)的集合,在使用时,基于maven构建,将对应相关功能所有技术类型的库的jar包坐标导入即可使用(相关类型所有类库,因为springboot不知道可能会使用那种技术类型,所以选择全部导入),并且spring boot会自动匹配无冲突的jar包依赖。
1.2springboot设计目的?
Springboot主要用于简化spring框架本身使用或者是集成其它框架时,应用搭建的过程。
零配置。无冗余代码生成和XML 强制配置,遵循“约定大于配置”。
集成大量常用第三方类库,几乎可以实现0配置,开箱即用。
只需要几个配置就可以快速搭建一套web项目或者构建一个微服务。

注意:spriingboot不是对spring框架的升级,它是基于spring框架开辟出的一种快速使用spring框架的方式。
1.3Springboot核心功能?
起步依赖 本质就是maven项目对象模型,就是使用maven构建一个springboot项目(可以是web项目或微服务项目),在pom.xml中导入对其它类库的依赖坐标,将这些类库打包到一起,并提供一些默认的功能。将当前使用springboot+maven构建的项目当作一个独立项目去运行。
起步依赖 作用 依赖传递

自动配置 Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的(完全自动化配置)。
二、springboot原理解析
2.1 springboot引导类解释

@SpringBootApplication  //该注解标识当前类是一个springboot启动类
public class MySpringBootApplication {
    public static void main(String[] args) {  //main函数表示程序入口
//run方法表示运行启动类,参数为当前类的字节码对象和对应参数
        SpringApplication.run(MySpringBootApplication.class,args);
    }
}

2.2 起步依赖原理
① 在pom.xml中查看父工程依赖的源码

<!--1.父工程 自动导入依赖的其它jar包-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
</parent>

② 进入spring-boot-starter-parent查看

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.1.6.RELEASE</version>
  <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

③ 进入spring-boot-dependencies查看

指定所有相关类库的jar包版本号(springboot已解决jar冲突问题)
<properties>
  <activemq.version>5.15.9</activemq.version>
  <antlr2.version>2.7.7</antlr2.version>
  ... ...
  <tomcat.version>9.0.21</tomcat.version>
</properties>
根据指定版本号,导入依赖的jar包
<dependencyManagement>
  <dependencies>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot</artifactId>
  <version>2.1.6.RELEASE</version>
 </dependency>
... ...
<dependency>
      <groupId>xml-apis</groupId>
      <artifactId>xml-apis</artifactId>
      <version>${xml-apis.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>
导入指定依赖的相关插件
<build>
  <pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.apache.johnzon</groupId>
        <artifactId>johnzon-maven-plugin</artifactId>
        <version>${johnzon.version}</version>
      </plugin>
      ... ...
<plugin>
        <groupId>pl.project13.maven</groupId>
        <artifactId>git-commit-id-plugin</artifactId>
        <version>${git-commit-id-plugin.version}</version>
      </plugin>
    </plugins>
  </pluginManagement>
</build>

④ 总结

通过以上jar包依赖源码查看,我们可以确定,当启动一个springboot应用时,springboot会根据导入在pxm.xml中的启动类(也叫启动器),自动为我们将所有可能需要使用的技术类型jar包的依赖全部导入,帮助开发人员进行jar包的配置与管理,使开发工作更加便捷。

2.3 自动配置原理

Springboot框架自动配置是根据引导类的@SpringBootApplication注解来完成的,该注解内部通过其它注解的标注,完成了自动配置。

下面逐个分析springboot通过哪些注解完成了自动配置功能

① @SpringBootApplication

该注解是一个复合注解,表示被它标注的类是一个springBoot的启动类(也叫引导类)。

我们点进去查看该注解的源码:

java springboot框架 springboot框架入门教程_xml


② @ComponentScan

首先第一个我们来看@ComponentScan注解,

该注解通过字面组成我们可以分为Component和Scan。

Component:表示被其标注的类是一个可以被spring容器加载的组件
Scan:表示扫描
所以@ComponentScan注解是用来做组件扫描的。

注意:使用@ComponentScan注解进行包扫描,它扫描的范围默认是以当前启动类所在的包为起点,然后扫描和启动类同级的所有包。所以我们在创建mvc三层包结构时,要保持和启动类同级,保证可以被扫描到。

那么被扫描到的包及子包下被@Controller、@Service、@Repository、@RestController、@Bean等注解修饰的类也就加载到spring容器中了,被spring容器管理。

③ @EnableAutoConfiguration

该注解表示开启自动配置,我们点进去查看该注解的源码

java springboot框架 springboot框架入门教程_加载_02


源码中的@AutoConfigurationPackage

表示自动配置包,它决定了我们在加载包及子包中的类时,是以启动类所在的包为起点。

它内部使用@Import(AutoConfigurationPackages.Registrar.class)

标识,在AutoConfigurationPackages下的registerBeanDefinitions

方法中实现获取主配置类下所有包及子包的组件导入到Spring 容器当中。

java springboot框架 springboot框架入门教程_java springboot框架_03


@Import(AutoConfigurationImportSelector.class)

该注解是导入自动配置类,@Import是spring框架的底层注解,我们来看下AutoConfigurationImportSelector类做了什么?源码解析:

(1)我们进入AutoConfigurationImportSelector类,定位到selectImports方法

java springboot框架 springboot框架入门教程_xml_04


(2)进入到getAutoConfigurationEntry方法中

java springboot框架 springboot框架入门教程_xml_05


(3)进入到getCandidateConfigurations方法中

java springboot框架 springboot框架入门教程_java springboot框架_06


上述代码中SpringFactoriesLoader.loadFactoryNames方法的作用就是从META-INF/spring.factories文件中读取指定类对应的类名称列表。也就是SpringBoot 在启动的时候就从类路径下的 META-INF/spring.factores 中获取EnableAutoConfiguration指定的值,将这些作为自动配置类导入到容器当中,自动配置类就生效,帮我们进行自动配置的工作。(4)我们看下META-INF/spring.factores中EnableAutoConfiguration指定的值是什么样子的?

java springboot框架 springboot框架入门教程_xml_07


④ 总结

自动配置就是基于复合注解@SpringBootApplication为源头,在引导类启动时就加载内部的配置类信息,实现将配置类信息交给SpringFactory加载器进行一系列的容器创建,从而实现自动配置。

三、springboot配置文件

3.1 思考

① springboot如何解决配置文件加载问题

在之前我们学习ssm框架或者使用ssm框架做项目开发时,我们定义的配置文件,比如applicationContext.xml,springmvc.xml,applicationContext-tx.xmld等文件是需要进行配置才能被加载使用的。

为什么springboot不需要进行配置文件的配置就可以完成加载呢?

或者Springboot为什么默认从resource目录下加载配置文件?

(1)在springboot的pom.xml中我们查看父工程坐标

java springboot框架 springboot框架入门教程_加载_08


我们可以看到在父工程中已经定义好加载路径,当项目启动时,直接去resource目录下去加载以application开头的配置文件,必须是application开头,否则加载不到。

② springboot配置文件中的配置项来源

java springboot框架 springboot框架入门教程_spring_09


3.2 springboot配置文件配置数据

① 配置普通数据

#yml文件配置普通数据
server:
  port: 8080

② 配置对象数据

#yml文件配置对象
user:
  username: zhangsan
  password: 123

③ 配置Map数据

#yml文件配置对象
user:
  username: zhangsan
  password: 123
  #yml文件配置Map数据
  mobiles:
    - num: 1001
      brand: 华为
    - num: 1002
      brand: 小米

④ 配置集合、数组数据

#yml文件配置对象
user:
  username: zhangsan
  password: 123
  #yml文件配置Map数据
  mobiles:
    - num: 1001
      brand: 华为
    - num: 1002
      brand: 小米
  #yml文件配置List数据
  nicknames:
    - java
    - php

⑤ 使用@value注解映射

person:
  name: xiaoming
  age: 18

使用:

@RestController
public class UserController {

    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private int age;

    @RequestMapping("/sayuser")
    public String sayuser(){
        System.out.println(name + "," +age);
       return "springboot 启动类演示!!!";
    }
}

3.3 springboot中配置文件优先级

① resource下yml和properties优先级

properties 优于 yml,当在resource下同时存在properties和yml时,properties配置覆盖yml。

② 目录路径下的properties和yml优先级

在springboot中,不止resource类路径下可以存放properties和yml文件,在项目根路径下、项目根路径config目录下、类路径内config子目录下也可以存放配置文件

java springboot框架 springboot框架入门教程_spring_10


优先级:1类路径下的 > 2类路径下的config目录下的 > 3根路径下 > 4根路径下config目录下的,另该路径的优先级是在springboot源码中加载时定义好的顺序。

四、springboot整合其它框架及使用

4.1 springboot整合mybatis

① 导入坐标

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.swk</groupId>
    <artifactId>springboot_3_mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--web启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--SpingBoot集成junit测试的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mybatis起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!-- MySQL连接驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--热部署配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

② 编写application.yml文件

#配置数据源
#&serverTimezone=UTC mysql默认采用美国时区,在pom文件中没有指定mysql驱动版本,默认使用最高版,造成安装mysql时的失去和系统时区存在差异
#解决方案:使用低版本mysql驱动(比如5.1.28),或者加上&serverTimezone=UTC
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://127.0.0.1:3306/sys?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver
#配置日志
logging:
  level:
    com.swk.dao: debug
#指定mybatis别名包
#指定mybatis xml映射文件路径
mybatis:
  type-aliases-package: com.swk.pojo
  mapper-locations: classpath:com/swk/dao/*.xml

③ 编写mapper.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="com.swk.dao.UserDao">
    <select id="findAll" resultType="user">
        select * from t_user
    </select>
</mapper>

④ 编写测试代码

@RunWith(SpringRunner.class)
@SpringBootTest
public class MapperTest {

    @Autowired
    private UserService userService;

    @Test
    public void testFindAll(){
        List<User> all = userService.findAll();
        for (User user : all) {
            System.out.println(user);
        }
    }
}

4.2springboot整合springdatajpa
① 导入坐标

<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.swk</groupId>
    <artifactId>springboot_4_datajpa</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--springboot web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--springboot 单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- springBoot JPA的起步依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- MySQL连接驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 配置redis启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

② 编写application.yml文件

#配置链接数据源
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://127.0.0.1:3306/sys?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver
#配置日志
logging:
  level:
    com.swk.dao: debug
#配置redis
redis:
  port: 6379
  host: 127.0.0.1
#配置jpa
#在jpa中ddl-auto一共有四种:分别为:
#ddl-auto: create ----每次运行该程序,没有表格会新建表格,表内有数据会清空;
#ddl-auto: create-drop ----每次程序结束的时候会清空表;
#ddl-auto: update ----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新;
#ddl-auto: validate ----运行程序会校验数据与数据库的字段类型是否相同,不同会报错;
jpa:
  database: mysql
  generate-ddl: true
  show-sql: true
  hibernate:
    ddl-auto: update
    naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy

③ 编写对用pojo类映射

@Entity
@Table(name = "t_user")
public class User  {
    // 主键
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    // 用户名
    @Column(name = "username")
    private String username;
    // 密码
    @Column(name = "password")
    private String password;
    // 姓名
    @Column(name = "name")
    private String name;
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

④ 编写dao层

public interface UserDao extends JpaRepository<User,Long> {}

⑤ 编写service层

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Override
    public void save(User user) {
        userDao.save(user);
    }
    @Override
    public void deleteUserById(Long id) {
        userDao.deleteById(id);
    }
    @Override
    public void updateUser(User user) {
        userDao.save(user);
    }
    @Override
    public User findUserById(Long id) {
        return userDao.findById(id).get();
    }
    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }
}

⑥ 编写controller

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/findAll")
    public List<User> findAll(){
        return userService.findAll();
    }
    @RequestMapping("/findOne")
    public User findOne(){
        return userService.findUserById(1L);
    }
    @RequestMapping("/saveUser")
    public void saveUser(){
        User user = new User();
        user.setUsername("ming");
        user.setPassword("123");
        user.setName("明");
        userService.save(user);
    }
    @RequestMapping("/deleteUser")
    public void deleteUserById(){
        userService.deleteUserById(3L);
    }
    @RequestMapping("/updateUser")
    public void updateUser(){
        User user = new User();
        user.setId(10L);
        user.setUsername("xiaoming");
        user.setPassword("123");
        user.setName("小明");
        userService.save(user);
    }
}

4.3 springboot整合redis
① 导入坐标

<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.swk</groupId>
    <artifactId>springboot_5_redis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--springboot web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--springboot 单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- springBoot JPA的起步依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--mybatis起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- MySQL连接驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 配置redis启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

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

② 编写application.yml文件

#配置mybatis
mybatis:
  type-aliases-package: com.swk.pojo
  mapper-locations: classpath:com/swk/dao/*.xml
#配置数据源
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://127.0.0.1:3306/sys?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver
#配置日志
logging:
  level:
    com.swk.dao: debug
#redis配置
redis:
  port: 6379
  host: 127.0.0.1

③ 业务处理

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RedisTemplate redisTemplate;
@Override
    public User findOne(Integer id) {
        String key = "user";
        //先去redis中查找是否有数据,有直接返回
        User user = (User) redisTemplate.boundValueOps(key).get();
        if(user!=null){
            return user;
        }else{
            user = userDao.findOne(id);
            if(user!=null){
                redisTemplate.boundValueOps(key).set(user);
            }
            return user;
        }

    }
}

4.4 springboot整合定时任务
① 导入坐标

<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.swk</groupId>
    <artifactId>springboot_6_CronJob</artifactId>
    <version>1.0-SNAPSHOT</version>
    <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 添加 Scheduled 坐标 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
    </dependencies>
</project>

② 测试类

@Component //任务类上写该注解,将当前的任务类注入到容器
public class TaskController {

    /**
     * @Scheduled定时任务注解及属性
     * fixedDelay属性:距离上一次定时任务执行完毕后N毫秒在执行
     * 比如:执行A任务花了5秒,设置参数是3000,A任务执行完成之后,在过3秒执行B任务
     *
     * 1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次
     * 2.zone表示执行时间的时区
     * 3.fixedDelay 和fixedDelayString 表示一个固定延迟时间执行,上个任务完成后,延迟多长时间执行
     * 4.fixedRate 和fixedRateString表示一个固定频率执行,上个任务开始后,多长时间后开始执行
     * 5.initialDelay 和initialDelayString表示一个初始延迟时间,第一次被调用前延迟的时间
     *
     */
    @Scheduled(fixedDelay=3000)
    public void myTask(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date()));
    }
}

@Component
public class TaskController2 {

    @Scheduled(cron="0/5 * * * * *")
    public void myTask(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(simpleDateFormat.format(new Date()));
    }
}

4.5 springboot整合thymleaf
① 导入坐标

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.swk</groupId>
    <artifactId>springboot_7_thymleaf</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

② 配置application.yml文件

spring:
  thymeleaf:
    cache: false

③ 创建templates文件夹
在resources目录下创建templates文件夹,用于存放使用thmleafi相关的前端页面代码,具体代码见⑤
④ 测试代码

@RequestMapping("/index")
@Controller
public class IndexController {
    @RequestMapping("/helloThymleaf")
    public String helloThymleaf(Model model){
        model.addAttribute("hello","hello thymleaf!!!");
        return "index";
    }
}
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/list")
    public String findAll(Model model){
        List<User> userlist = new ArrayList<>();
        userlist.add(new User(1,"java","北京"));
        userlist.add(new User(2,"PHP","上海"));
        userlist.add(new User(3,"c++","深圳"));
        userlist.add(new User(4,"python","杭州"));
        model.addAttribute("userlist",userlist);
        return "userlist";
    }

    @RequestMapping("/map")
    public String getMap(Model model){
        Map<String,Object> map = new HashMap<>();
        map.put("id","5");
        map.put("username","小明");
        map.put("address","广州");
        model.addAttribute("map",map);
        return "usermap";
    }

    @RequestMapping("/arr")
    public String getArr(Model model){
        String[] names = {"小红","小紫","小白","小黑"};
        model.addAttribute("names",names);
        return "userarr";
    }

    @RequestMapping("/getDate")
    public String getDate(Model model){
        model.addAttribute("date",new Date());
        return "userdate";
    }

    @RequestMapping("/getif")
    public String getif(Model model){
        model.addAttribute("age",22);
        return "userif";
    }

    @RequestMapping("/include")
    public String include(Model model){
        model.addAttribute("age",22);
        return "userinclude";
    }
}

⑤ 前端代码

插值表达式
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p th:text="${hello}"></p>

    <form th:action="@{/index/helloThymleaf}">
        <button>提交</button>
    </form>
</body>
</html>
数组展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div th:each="name,namestat:${names}">
        <span th:text="${namestat.count}"></span>
        <span th:text="${name}"></span>
    </div>
</body>
</html>
日期类展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <span th:text="${date}"></span><br>
        <span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}"></span>
    </div>
</body>
</html>
If判断
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--th:unless表示条件不成立-->
    <div>
        <span th:text="${age}"></span>
        <span th:if="${age>=18}">长大成人</span>
        <span th:unless="${age<18}">小屁孩</span>
    </div>
</body>
</html>
List展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1">
        <tr>
            <td>下标</td>
            <td>编号</td>
            <td>姓名</td>
            <td>地址</td>
        </tr>
        <tr th:each="user,userstat:${userlist}">
            <td th:text="${userstat.index}"></td>
            <td th:text="${user.id}"></td>
            <td th:text="${user.username}"></td>
            <td th:text="${user.address}"></td>
        </tr>
    </table>
</body>
</html>
Map展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <!--直接获取map中的值-->
        <span th:text="${map.id}"></span>
        <span th:text="${map.username}"></span>
        <span th:text="${map.address}"></span>
    </div>
    <hr/>
    <div>
        <!--遍历map-->
        <div th:each="map:${map}">
            <span th:text="${map.key}"></span><span th:text="${map.value}"></span>
        </div>
    </div>
</body>
</html>