推荐阅读:

肝了一周总结的SpringBoot实战教程,太实用了!

一、SpringBoot 基础

1. SpringBoot 简介

1.1 Spring 缺点

  • 配置复杂
  • 依赖管理比较麻烦,费时费力

1.2 SpringBoot 特点

  • 起步依赖,就是将具备某种功能的坐标打包到一起,并提供一些默认的功能
  • 自动配置,开箱即用,没有代码生成,也无需 xml 配置

2. SpringBoot 快速入门

2.1 手动创建项目

创建基本 maven 工程

添加 SpringBoot 起步依赖

SpringBoot 要求,项目要继承 SpringBoot 的起步依赖 spring-boot-starter-parent

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

SpringBoot 要集成 SpringMVC 进行 Controller 的开发,所以项目要导入 web 的启动依赖

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

编写 SpringBoot 引导类

要通过 SpringBoot 提供的引导类起步 SpringBoot 才可以进行访问

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 声明此类是引导类
@SpringBootApplication
public class MySpringBootApplication {
  public static void main(String[] args) {
    // 启动程序,传入引导类字节码对象
    SpringApplication.run(MySpringBootApplication.class);
  }
}

我们需要将引导类放置在项目的根包目录下,与 comtroller,service,dao 包平级,springboot 会自动扫描与引导类平级的包及其子目录下文件的注解

然后编写 controller ,即可发现能够使用

2.2 自动生成项目

使用 idea 新建项目的时候不要选择 maven,选择左边的 Spring Initializr

根据需求勾选需要组件即可

自动生成的 ServletInitializer 说明

ServletInitializer.java

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringSecurityApplication.class);
    }
    
}

Springboot 启动方式有多种,常用的就是 application 启动类启动,直接 run 即可。

我们也可以使用外置 tomcat 启动,这时候就使用到了此类,此类需要继承 SpringBootServletInitializer 类并复写 configure() 方法,SpringBootServletInitializer 的执行过程,简单来说就是通过 SpringApplicationBuilder 构建并封装 SpringApplication 对象,并最终调用 SpringApplication 的 run 方法的过程。

SpringBootServletInitializer 就是原有的 web.xml 文件的替代。

2.3 自动生成项目依赖说明

2.3.1 Developer Tools

Spring Boot Devtools

热部署使用,具体请看 2.4

Spring Configuration Processor

依赖作用:spring-configuration-metadata.json文件是做啥的?

spring boot 默认使用 yml/properties 中的配置,但有时候要用传统的 xml 或 其他配置文件,这时候就需要用到 spring configuration processor。
在配置类开头加上 @PropertySource("classpath:your.xml"),其余用法与加载 yml 的配置一样

@PropertySource 中的属性

  • value:指明加载配置文件的路径。
  • ignoreResourceNotFound:指定的配置文件不存在是否报错,默认是false。当设置为 true 时,若该文件不存在,程序不会报错。实际项目开发中,最好设置 ignoreResourceNotFound 为 false。
  • encoding:指定读取属性文件所使用的编码,我们通常使用的是UTF-8。

@ConfigurationProperties 设定前缀,这样就不用在每个属性前面设置 @Value("${user.*}")

@ConfigurationProperties(prefix = "user")
@PropertySource(value = {"classpath:resources/user.xml"},
        ignoreResourceNotFound = false, encoding = "UTF-8")
// 自动读取配置文件中的 user.name,user.age 赋给对应变量
public class User {
    private String name;
    private int age;
}

2.3.2 Web

Spring Web

构建 web 项目,使用 spring mvc 框架,使用 tomcat 当做默认服务器

2.4 SpringBoot 工程热部署

添加依赖

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

开启自动编译

Idea -> settings -> build、execution、deployment -> compiler -> 勾选 Build project automatically

设置注册表

然后 shift+ctrl+alt+/ -> 选择 registry -> 勾选 compiler.automake.allow.when.runing

3. SpringBoot 原理分析

3.1 分析 spring-boot-starter-parent

查看 pom.xml 中,parent 标签中 spring-boot-starter-parent, 跳转到了 spring-boot-starter-parent 的 pom.xml,重点部分如下

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.4.2</version>
</parent>

<resource>
  <directory>${basedir}/src/main/resources</directory>
  <filtering>true</filtering>
  <includes>
    <include>**/application*.yml</include>
    <include>**/application*.yaml</include>
    <include>**/application*.properties</include>
  </includes>
</resource>

我们发现自动扫描了 resources 中以 application 开头的三个配置文件,我们一般使用 yml 来替换默认配置,注意,如果我们既使用了 yml 也使用了 properties,则properties 配置会覆盖 yml 配置。

filtering 的作用参考:maven Filtering true 作用

我们继续查看 spring-boot-starter-parent 的 parent,spring-boot-dependencies

<properties>
    <activemq.version>5.15.3</activemq.version>
    <antlr2.version>2.7.7</antlr2.version>
    <appengine-sdk.version>1.9.63</appengine-sdk.version>
    <artemis.version>2.4.0</artemis.version>
    <aspectj.version>1.8.13</aspectj.version>
    <assertj.version>3.9.1</assertj.version>
    <atomikos.version>4.0.6</atomikos.version>
    <bitronix.version>2.1.4</bitronix.version>
    <build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
    <byte-buddy.version>1.7.11</byte-buddy.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
            </plugin>
            <plugin>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-codegen-maven</artifactId>
                <version>${jooq.version}</version>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.0.1.RELEASE</version>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

从上面的 pom.xml 中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的 SpringBoot 工程继承 spring-boot-starter-parent 后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。

3.2 分析 spring-boot-starter-web

查看 pom.xml 中的 spring-boot-starter-web,跳转到了spring-boot-starter-web 的pom.xml,xml 配置如下(只摘抄了部分重点配置):

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.4.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-json</artifactId>
      <version>2.4.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.4.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.3</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

从上面的 spring-boot-starter-web 的 pom.xml 中我们可以发现,spring-boot-starter-web 就是将 web 开发要使用的 spring-web、spring-webmvc 等坐标进行了“打包”,这样我们的工程只要引入 spring-boot-starter-web 起步依赖的坐标就可以进行 web 开发了,同样体现了依赖传递的作用。

3.3 自动配置原理解析

查看启动类的注解 @SpringBootApplication,源码如下

@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 {
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};
}
  • @SpringBootConfifiguration:等同与 @Confifiguration,既标注该类是 Spring的一个配置类
  • @EnableAutoConfifiguration:SpringBoot 自动配置功能开启

查看注解 @EnableAutoConfifiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

其中,@Import(AutoConfifigurationImportSelector.class) 导入了AutoConfifigurationImportSelector 类,查看源码

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    configurations = getConfigurationClassFilter().filter(configurations);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
}

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct.");
    return configurations;
}

其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是从 META-INF/spring.factories 文件中读取指定类对应的类名称列表

image.png

如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\

上面配置文件存在大量的以 Confifiguration 为结尾的类名称,这些类就是存有自动配置信息的类,而 SpringApplication 在获取这些类名后再加载。

我们以 ServletWebServerFactoryAutoConfiguration 为例来分析源码:

@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {}

其中,@EnableConfifigurationProperties(ServerProperties.class) 代表加载 ServerProperties 服务器配置属性类

源码如下:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
	private Integer port;
	private InetAddress address;
}

其中,prefifix = "server" 表示 SpringBoot 配置文件中的前缀,SpringBoot 会将配置文件中以 server 开始的属性映射到该类的字段中。映射关系如下:

image.png

然后查看 spring-boot-autoconfigure 下的 META-INF/spring-configuration-metadata.json ,能够发现如下默认配置

{
	"name": "server.port",
	"type": "java.lang.Integer",
	"description": "Server HTTP port.",
	"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
	"defaultValue": 8080
}

我们可以自定义配置文件来替换默认配置。

4. SpringBoot 的配置文件

SpringBoot 是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,一般使用 application.properties 或者 application.yml(application.yaml)进行配置。

SpringBoot 默认会从 resources 目录下加载 application.properties 或 application.yml(application.yaml)文件

配置信息的查询,上面有提及从源码中查找的方式,也可以从文档查找

文档URL:https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#common-application-properties

常用的配置摘抄如下:

# QUARTZ SCHEDULER (QuartzProperties) 
spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode. 
spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql # Path to the SQL file to use to initialize the database schema. 
spring.quartz.job-store-type=memory # Quartz job store type.
spring.quartz.properties.*= # Additional Quartz Scheduler properties.

# ---------------------------------------- 
# WEB PROPERTIES 
# ---------------------------------------- 

# EMBEDDED SERVER CONFIGURATION (ServerProperties) 
server.port=8080 # Server HTTP port. 
server.servlet.context-path= # Context path of the application. 
server.servlet.path=/ # Path of the main dispatcher servlet. 

# HTTP encoding (HttpEncodingProperties) 
spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly. 

# JACKSON (JacksonProperties) 
spring.jackson.date-format= # Date format string or a fully-qualified date format class name. For instance, `yyyy-MM-dd HH:mm:ss`. 

# SPRING MVC (WebMvcProperties) 
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the dispatcher servlet. 
spring.mvc.static-path-pattern=/** # Path pattern used for static resources. 
spring.mvc.view.prefix= # Spring MVC view prefix. 
spring.mvc.view.suffix= # Spring MVC view suffix. 

# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) 
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto- detected based on the URL by default. 
spring.datasource.password= # Login password of the database. 
spring.datasource.url= # JDBC URL of the database. 
spring.datasource.username= # Login username of the database. 

# JEST (Elasticsearch HTTP client) (JestProperties) 
spring.elasticsearch.jest.password= # Login password. 
spring.elasticsearch.jest.proxy.host= # Proxy host the HTTP client should use. 
spring.elasticsearch.jest.proxy.port= # Proxy port the HTTP client should use. 
spring.elasticsearch.jest.read-timeout=3s # Read timeout. 
spring.elasticsearch.jest.username= # Login username.

我们可以通过配置 application.poperties 或者 application.yml 来修改 SpringBoot 的默认配置

例如

# application.properties 文件
server.port=8888 
server.servlet.context-path=demo

# application.yml 文件
server: 
  port: 8888 
  servlet: 
    context-path: /demo

5. 配置文件与配置类的属性映射方式

参考:springboot 读取配置文件

6. SpringBoot 整合其他技术

6.1 整合 Mybatis

添加依赖

<!--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>

配置连接信息

application.properties

#DB Configuration: 
spring.datasource.driverClassName=com.mysql.jdbc.Driver 
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 
spring.datasource.username=root 
spring.datasource.password=root

编写业务

**在 application.properties 中添加 mybatis 的信息 **

#spring集成Mybatis环境 
#pojo别名扫描包 
mybatis.type-aliases-package=com.itheima.domain 
#加载Mybatis映射文件 
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

6.2 整合 Junit

添加依赖

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

编写测试类

package com.itheima.test;

import com.itheima.MySpringBootApplication;
import com.itheima.domain.User;
import com.itheima.mapper.UserMapper;
import java.util.List;
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.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
public class MapperTest {

  @Autowired
  private UserMapper userMapper;

  @Test
  public void test() {
    List<User> users = userMapper.queryUserList();
    System.out.println(users);
  }
}
  • SpringRunner 继承自 SpringJUnit4ClassRunner,使用哪一个 Spring 提供的测试测试引擎都可以。
  • @SpringBootTest 的属性指定的是引导类的字节码对象

6.3 整个 Redis

添加依赖

<!-- 配置使用redis启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置连接信息

# Redis 
spring.redis.host=127.0.0.1 
spring.redis.port=6379

测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootJpaApplication.class)
public class RedisTest {

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private RedisTemplate<String, String> redisTemplate;

  @Test
  public void test() throws JsonProcessingException { //从redis缓存中获得指定的数据
    String userListData = redisTemplate.boundValueOps("user.findAll").get();
    //如果redis中没有数据的话
    if (null == userListData) {
      //查询数据库获得数据
      List<User> all = userRepository.findAll();
      //转换成json格式字符串
      ObjectMapper om = new ObjectMapper();
      userListData = om.writeValueAsString(all);
      //将数据存储到redis中,下次在查询直接从redis中获得数据,不用在查询数据库
      redisTemplate.boundValueOps("user.findAll").set(userListData);
      System.out.println("===============从数据库获得数据===============");
    } else {
      System.out.println("===============从redis缓存中获得数据===============");
    }
    System.out.println(userListData);
  }
}

6.4 整合 Spring Data JPA

添加依赖

<!-- springBoot JPA的起步依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--jdk9需要导入如下坐标-->
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>

配置文件

application.properties

#DB Configuration: 
spring.datasource.driverClassName=com.mysql.jdbc.Driver 
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 
spring.datasource.username=root 
spring.datasource.password=root 

#JPA Configuration: 
spring.jpa.database=MySQL 
spring.jpa.show-sql=true 
spring.jpa.generate-ddl=true 
spring.jpa.hibernate.ddl-auto=update 
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy

创建实体类

@Entity
public class User {
  // 主键
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id; // 用户名
  private String username; // 密码
  private String password; // 姓名
  private String name;
  //此处省略setter和getter方法... ...
}

编写 UserRepository

public interface UserRepository extends JpaRepository<User, Long> {
  public List<User> findAll();
}

编写测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
public class JpaTest {

  @Autowired
  private UserRepository userRepository;

  @Test
  public void test() {
    List<User> users = userRepository.findAll();
    System.out.println(users);
  }
}

二、spring-boot-starter

参考文档:
附加:Spring Boot项目中,spring相关依赖分析;(主要是spring-boot-starter依赖、spring-boot-starter-web依赖等)
SpringBootStarter的原理以及自定义简单的starter步骤

聊完基础,我们探讨一下 spring-boot-starter 到底起了什么作用。

1. Starter 是什么

Starter 是 Spring Boot 的四大核心功能特性之一,除此之外,Spring Boot 还有自动装配、Actuator 监控等特性。Spring Boot 里面的这些特性,都是为了让开发者在开发基于 Spring 生态下的企业级应用时,只需要关心业务逻辑,减少对配置和外部环境的依赖。

其中,Starter 是启动依赖,它的主要作用有几个。

  1. Starter 组件以功能为纬度,来维护对应的jar包的版本依赖,使得开发者可以不需要去关心这些版本冲突这种容易出错的细节。
  2. Starter 组件会把对应功能的所有jar包依赖全部导入进来,避免了开发者自己去引入依赖带来的麻烦。
  3. Starter 内部集成了自动装配的机制,也就说在程序中依赖对应的 starter 组件以后,这个组件自动会集成到 Spring 生态下,并且对于相关 Bean 的管理,也是基于自动装配机制来完成。
  4. 依赖 Starter 组件后,这个组件对应的功能所需要维护的外部化配置,会自动集成到 Spring Boot 里面,我们只需要在application.properties 文件里面进行维护就行了,比如 Redis这 个 starter,只需要在 application.properties 文件里面添加 redis 的连接信息就可以直接使用了。

Starter 组件几乎完美的体现了 Spring Boot 里面约定优于配置的理念。

img

另外,Spring Boot 官方提供了很多的 Starter 组件,比如 Redis、JPA、 MongoDB 等等。但是官方并不一定维护了所有中间件的 Starter,所以对于不存在的 Starter,第三方组件一般会自己去维护一个。官方的 starter 和第三方的 starter 组件,最大的区别在于命名上。

  1. 官方维护的 starter: spring-boot-starter-xxx
  2. 第三方维护的 starter: xxx-spring-boot-starter

2. 自定义 starter

pom.xml

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>
    <groupId>cn.test</groupId>
    <artifactId>hello-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

config 文件

@Configuration
@ConfigurationProperties(prefix = "request-log")
public class TestConfig {

    @Bean
    @ConditionalOnProperty(prefix = "request-log", name = "enable", havingValue = "true")
    public RequestLogInterceptor requestLogInterceptor() {
        return new RequestLogInterceptor();
    }
}

META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.rs.starter.log.RequestLogConfig

然后别的工程引用就行。

3. 自动配置条件

在 bean 上,我们可以配置完成自动配置的条件,比如

@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusProperties.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {}
注解 功能说明
@ConditionalOnBean 仅在当前上下文中存在某个bean时,才会实例化这个Bean
@ConditionalOnClass 某个class位于类路径上,才会实例化这个Bean
@ConditionalOnExpression 当表达式为true的时候,才会实例化这个Bean
@ConditionalOnMissingBean 仅在当前上下文中不存在某个bean时,才会实例化这个Bean
@ConditionalOnMissingClass 某个class在类路径上不存在的时候,才会实例化这个Bean
@ConditionalOnNotWebApplication 不是web应用时才会实例化这个Bean
@AutoConfigureAfter 在某个bean完成自动配置后实例化这个bean
@AutoConfigureBefore 在某个bean完成自动配置前实例化这个bean

4. spring-boot-starter-parent 的作用

我们先看下创建 springboot 项目的两种方式 :spring-boot-starter-parent 与 spring-boot-dependencies区别

当我们创建一个 Spring Boot 工程时,可以继承自一个 spring-boot-starter-parent, 也可以不继承自它,我们先来看第一种情况。

4.1 继承 parent

先来看 parent 的基本功能有哪些?

  1. 定义了 Java 编译版本为 1.8。
  2. 使用 UTF-8 格式编码。
  3. 继承自 spring-boot-dependencies,这个里边定义了依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号。
  4. 执行打包操作的配置。
  5. 自动化的资源过滤。
  6. 自动化的插件配置。
  7. 针对 application.propertiesapplication.yml 的资源过滤,包括通过 profile 定义的不同环境的配置文件,例如 application-dev.properties application-devyml

请注意,由于 application.properties和application.yml 文件接受 Spring 样式占位符 ${...},因此 Maven 过滤更改为使用 @...@ 占位符,当然开发者可以通过设置名为 resource.delimiter 的Maven 属性来覆盖@...@ 占位符。

4.2 spring-boot-dependencies

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这样写之后,依赖的版本号问题虽然解决了,但是关于打包的插件、编译的 JDK版本、文件的编码格式等等这些配置,在没有 parent 的时候, 这些统统要自己去配置。

5. springboot 常见依赖

  1. spring-boot-starter 这是 Spring Boot 的核心启动器,包含了自动配置、日志和 YAML。
  2. spring-boot-starter-amqp 通过 spring-rabbit 来支持 AMQP 协议(Advanced Message Queuing Protocol。
  3. spring-boot-starter-aop 支持面向方面的编程即 AOP,包括 spring-aop 和 AspectJ。
  4. spring-boot-starter-artemis 通过 Apache Artemis 支持 JMS 的 API (Java Message Service APl。
  5. spring-boot-starter-batch 支持 Spring Batch,包括 HSQLDB 数据库。
  6. spring-boot-starter-cache 支持 Spring 的 Cache 抽象。
  7. spring-boot-starter-cloud-connectors 支持Spring Cloud Connectors,简化了在像 Cloud Foundry 或 Heroku 这样的云平台上连接服务。
  8. spring-boot-starter-data-elasticsearch 支持 ElasticSearch 搜索和分析引擎,包括 spring-data-elasticsearch。
  9. spring-boot-starter-data-gemfire 支持 GemFire 分布式数据存储,包括 spring-data-gemfire。
  10. spring-boot-starter-data-jpa 支持 JPA (Java Persistence APl,包括spring-data-jpa、 spring-orm、 Hibernate。
  11. spring-boot-starter-data-mongodb 支持 MongoDB 数据,包括 spring-data-mongodb。
  12. spring-boot-starter-data-rest 通过 spring-data-rest-webmvc,支持通过 REST 暴露 Spring Data 数据仓库。
  13. spring-boot-starter-data-solr 支持 Apache Solr 搜索平台,包括 spring-data-solr。
  14. spring-boot-starter-freemarker 支持 FreeMarker 模板引擎。
  15. spring-boot-starter-groovy-templates 支持 Groovy 模板引擎。
  16. spring-boot-starter-hateoas 通过 spring-hateoas 支持基于 HATEOAS 的 RESTful Web 服务。
  17. spring-boot-starter-hornetq 通过 HornetQ 支持 JMS。
  18. spring-boot-starter-integration 支持通用的 spring-integration 模块。
  19. spring-boot-starter-jdbc 支持 JDBC 数据库。
  20. spring-boot-starter -jersey 支持 Jersey RESTful Web 服务框架。
  21. spring-boot-starter-jta-atomikos 通过 Atomikos 支持 JTA 分布式事务处理。
  22. spring-boot-starter-jta-bitronix 通过 Bitronix 支持 JTA 分布式事务处理。
  23. spring-boot-starter-mail 支持 ijavax.mail 模块。
  24. spring-boot-starter-mobile 支持 spring-mobile。
  25. spring-boot-starter-mustache 支持 Mustache 模板引擎。
  26. spring-boot-starter-redis 支持 Redis 键值存储数据库,包括 spring-redis。
  27. spring-boot-starter-security 支持 spring-security。
  28. spring-boot-starter-social-facebook 支持 spring-social-facebook
  29. spring-boot-starter-social-linkedin 支持 pring-social-linkedin
  30. spring-boot-starter-social-twitter` 支持 pring-social-twitter
  31. spring-boot-starter-test 支持常规的测试依赖,包括 JUnit、 Hamcrest. Mockito 以及 spring-test 模块。
  32. spring-boot-starter-thymeleaf 支持 Thymeleaf 模板引擎,包括与 Spring 的集成。
  33. spring-boot-starter-velocity 支持 Velocity 模板引擎。
  34. spring-boot-starter-web 支持全栈式 Web 开发,包括 Tomcat 和 spring-webmvc。
  35. spring-boot-starter-websocket 支持 WebSocket 开发。
  36. spring-boot-starter-ws 支持 Spring Web Services。
  37. spring-boot-starter-actuator 增加了面向产品上线相关的功能,比如测量和监控。
  38. spring-boot-starter-remote-shell 增加了远程 ssh shell 的支持。
  39. spring-boot-starter-jetty 引入了 Jetty HTTP 引擎(用于替换 Tomcat)。
  40. spring-boot-starter-log4j 支持 Log4J 日志框架。
  41. spring-boot-starter-logging 引入了 Spring Boot 默认的日志框架 Logback。
  42. spring-boot-starter-tomcat 引入了 Spring Boot 默认的 HTTP 引擎 Tomcat。
  43. spring-boot-starter-undertow 引入了 Undertow HTTP 引擎(用于替换 tomcat)

三、springboot 生命周期

SpringBoot 生命周期