Spring Boot 2.x

Spring Boot 2.x


(一)设计目的

  • 简化Spring应用程序的初始搭建和开发过程

(二)设计理念

  • 约定优于配置(Convention Over Configuration)

(三)特性

详细情况,见《Spring Boot官方文档》

【1】SpringApplication

(1)控制台日志

控制台默认只显示INFO级别的日志,如果需要查看启动失败时具体报错,可以设置为DEBUG级别。或者通过java -jar xxx.jar --debug启动

(2)自定义Banner

  1. banner.txt添加到classpath
  2. 如果想自定义banner.txt文件位置,可以在application.properties添加spring.banner.location属性;如果文件编码非UTF-8,可以通过spring.banner.charset设置
  3. 如果想通过banner.gif/banner.jpg/banner.png设置,可以通过spring.banner.image.location设置

(3)事件 & 监听器

由于有些事件在ApplicationContext创建前就被触发,所以不能用@Bean注册,需要使用SpringApplication.addListeners(...)设置监听器

程序运行时,事件发送的顺序:

  1. ApplicationStartingEvent:在运行开始时、但在任何处理(除了监听器和初始化器注册)之前发送

  2. ApplicationEnvironmentPreparedEvent:在已知要在上下文中使用的Environment、但在上下文被创建之前发送

  3. ApplicationPreparedEvent:在Bean定义(BeanDefinition)被加载之后、refresh()开始之前发送

    refresh()方法是Spring的核心,其中完成了IoC容器的初始化

  4. ApplicationStartedEvent:上下文被刷新(refresh())之后、ApplicationRunner/CommandLineRunner被调用之前发送

  5. ApplicationReadyEventApplicationRunner/CommandLineRunner被调用之前发送,这个事件标志着应用可以接受服务请求了

  6. ApplicationFailedEvent:启动异常时发送

(4)网络环境(ApplicationContext

SpringApplication会尝试替你创建正确类型的ApplicationContext,它的算法很简单:

  1. 如果存在Spring MVC:创建AnnotationConfigServletWebServerApplicationContext
  2. 如果存在Spring WebFlux、不存在Spring MVC:创建AnnotationConfigReactiveWebServerApplicationContext

    这意味着如果你在同一个应用中同时使用了Spring MVCSpring WebFlux,应用会默认设置为Spring MVC

通过调用setWebApplicationType(WebApplicationType)可以覆盖
如果是JUnit单元测试中,可以setWebApplicationType(WebApplicationType.NONE)

  1. 其他情况:创建AnnotationConfigApplicationContext
  2. 通过调用setApplicationContextClass(...)可以完全控制ApplicationContext的类型

(5)获取应用参数(ApplicationArguments

如果想访问传递给SpringApplication.run(...)的参数,可以注入(@Autowired)一个org.springframework.boot.ApplicationArguments Bean:

1
2
3
4
5
6
7
8
9
@Component
public class MyBean{
@Override
public MyBean(ApplicationArguments args){
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
//...
}
}

(6)ApplicationRunner/CommandLineRunner

如果想在SpringApplication已启动就运行特定代码,可以引用ApplicationRunner/CommandLineRunner接口,两个接口都只提供一个run()方法,一旦SpringApplication.run(...)运行结束就被调用。

  1. ApplicationRunner传入ApplicationArguments实例作为参数
1
2
3
4
5
6
@Component
public class MyBean implements ApplicationRunner{
public void run(ApplicatioArguments args){
//...
}
}
  1. CommandLineRunner传入String数组作为参数
1
2
3
4
5
6
@Component
public class MyBean implements CommandLineRunner{
public void run(String... args){
//...
}
}

【2】外部化配置

SpringBoot允许通过application.properties/application.yml/环境变量/命令行参数将配置外部化,通过@Value/Environment/@ConfigurationProperties可以直接注入属性值。

随机值

RandomValuePropertySource可以生产随机的属性值,用于注入:

1
2
3
4
5
6
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

【3】根据环境切换配置文件

  1. @Profile("xxx"):加在@Component/@Configuration上可以指定属性生效的环境
1
2
3
4
5
@Configuration
@Profile("prod")
public class ProdConfiguration{
//生产环境配置
}
  1. spring.profile.active:配置在application.properties/application.yml中,可以设置生效的配置文件(比如application-prod.yml
1
spring.profile.avtive=prod,pre

注意:在application-prod.yml中要加spring.profiles属性指明配置文件的名称

1
2
3
4
5
6
spring:
profiles: prod
# 添加其他配置
# spring.profiles.include:
# - proddb
# - prodmq
  1. --spring.profile.avtive=prod,pre:加在命令行后
  2. SpringApplication.setAdditionalProfiles(...):加在程序中

【4】日志

  • Spring Boot内部日志默认使用的是Apache Commons Logging,但是也提供了Java Util Logging/Log4J2/Logback的默认配置,默认使用控制台输出,可以配置为使用文件输出。
  • 如果使用starters,默认日志是Logback

日志格式

1
2
3
4
5
2019-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2019-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2019-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2019-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  1. 日期、时间(ms级别),方便排序
  2. 日志级别:INFOERRORWARNTRACEDEBUG
  3. 进程ID
  4. 分隔符---:标明实际日志内容开始
  5. 使用[]包起来的线程名称
  6. 记录器名称:一般是记录日志的类名
  7. 日志信息

输出DEBUG/TRACE日志

默认情况下,只有ERROR/WARN/INFO级别的日志会输出,想要输出DEBUG/TRACE日志可以有以下几种方法:

  1. 命令行启动应用时使用:java -jar xx.jar --debugjava -jar xx.java --trace
  2. application.properties中加:debug=truetrace=true

将日志输出到文件

  • application.properties文件中添加logging.file/logging.path属性,可以将日志输出到文件
  • 默认只会输出INFO/ERROR/WARN级别的日志
  • 日志文件默认最大10MB,超过10MB会被截断,产生新的日志文件,可以通过logging.file.max-size进行配置

【5】验证(@Validated

  • 通过javax.validation可以对方法的参数/返回值进行验证
  • 在需要验证的类上要加@Validated注解
1
2
3
4
5
6
7
8
9
10
//需要验证的类要加@Validated注解
@Validated
@Bean
public class MyBean{
//通过@Size(min,max)注解验证第一个参数,保证其值在8-10之间
public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
Author author){
//...
}
}

【6】部署

(1)部署到云端

参考Alibaba Cloud Toolkit教程》一文中普通部署和使用Alibaba Cloud Toolkit部署部分。

(2)将应用安装为服务

除了使用java -jar来运行Spring Boot应用外,也可以将应用注册到init.dsystemd成为服务

使用init.d的步骤
  1. 添加Maven打包依赖:
1
2
3
4
5
6
7
<plugin> 
<groupId> org.springframework.boot </ groupId>
<artifactId> spring-boot-maven-plugin </ artifactId>
<configuration>
<executable> true </ executable>
</ configuration>
</ plugin>
  1. mvn package后发送到服务器
  2. 注册服务,并设置为开机自启动
1
sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
  1. 启动服务:
1
service myapp start

(四)启动(Bootstrap)类注解

  • @SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

@Configuration:提供了JavaConfig配置类实现;
@ComponentScan:扫描@Component等注解,将相关的Bean定义批量加载到IoC容器中;
@EnableAutoConfiguration:类的动态加载

1
2
3
4
5
6
7
8
9
10
@Target(ElementType.TYPE)
@Rentention(RententionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
//...
}

使用:

1
2
3
4
5
6
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}

SpringApplication.run()方法源码分析


(五)starter

@EnableAutoConfigurationstarter可以配合使用,用于导入Spring Boot应用启动需要的JAR包。

1.Spring Data

  • Spring DataSpring家族中专门用于数据访问的抽象框架,其核心理念是支持对所有存储媒介进行资源配置,从而实现数据访问。
  • Spring Data基于Repository架构模式并抽象出一套实现该模式的同意数据访问方式。
  1. Repositoty接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//空接口,通过泛型指定了领域实体对象的类型和主键ID
public interface Repository<T, ID> {}

//对Repository接口的扩展,实现了CRUD功能
public interface CrudRepository<T, ID> extends Repository<T, ID>{
<S extends T> S save(S entity); //保存单个
<S extends T> Iterable<S> saveAll(Iterable<S> entities); //保存全部
Optional<T> findById(ID id); //通过ID查找
boolean existesById(ID id); //判断ID是否存在
Iterable<T> findAll(); //查找全部
Iterable<T> findAllById(Iterable<ID> ids); //通过ID查找
long count(); //计数
void deleteById(ID id); //通过ID删除
void delete(T entity); //删除实体
void deleteAll(Iterable<? extends T> entities); //删除迭代器中的全部
void deleteAll(); //删除全部
}
  1. @Query查询:直接在代码中嵌入查询语句和条件
1
2
@Query("select a from Accout a where a.userName = ?1")
Accout findByUserName(String userName);
  1. 方法名衍生查询
1
List<Accout> findByFirstNameAndLastName(String firstName, String lastName);
  1. 分页Pageable & 排序Sort
1
2
3
4
5
//分页查询
Page<Account> findByFirstName(String firstName, Pageable pageable);

//排序
List<Accout> findByFirstName(String firstName, Sort sort);
  1. QueryByExample机制:允许动态查询,并且不需要编写包含字段名称的查询方法
  • Probe包含对应字段的实例对象
  • ExampleMatcher携带有关如何匹配特定字段的详细信息,相当于匹配条件
  • Example = Probe + ExampleMatcher用于构建具体的查询操作

MyBatis


JPA

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

Redis

  • 使用Spring Data Redis的第一步就是连接Redis服务器,想要实现连接,就需要获取RedisConnection

  • 通过RedisConnectionFactory接口获取RedisConnection

    常见的ConnectionFactoryJedisConnectionFactoryLettuceConnectionFactory两种。
    JedisConnectionFactory直连Redis,多线程环境下非线程安全,除非使用连接池为每个Jedis实例增加物理连接
    LettuceConnectionFactor基于Netty创建连接实例,可以在多个线程间实现线程安全,满足多线程环境下的并发访问要求。更重要的是LettuceConnectionFactor支持响应式的数据访问用法,它是ReactiveRedisConnectionFactory的一种实现类

  • Spring Data RedisRedis操作做了封装,提供了一个工具类RedisTemplate,通过注册RedisConnectionFactoryRedisTemplate中,该RedisTemplate就能获取RedisConnection

  • Redis TemplateRedis交互提供了一层高级别的抽象,当RedisConnection提供低级别的方法来发送和返回二进制数据,RedisTemplate能够实现序列化和连接过程的自动化管理

    GenericToStringSerializer:使用Spring转换服务进行序列化。
    JacksonJsonRedisSerializer:使用Jackson1将对象序列化为JSON
    Jackson2JsonRedisSerializer:使用Jackson2将对象序列化为JSON
    JdkSerializtionRedisSerializer:使用Java序列化。
    OxmSerializer:使用Spring O/X映射的编排器和解排器实现序列化,用于XML序列化。
    StringRedisSerializer:序列化String类型的key/value。

  • RedisTemplate提供丰富的接口操作Redis数据类型:ValueOperationsListOperationsSetOperationsZSetOperationsHashOperations,分别对应StringListSetZSetHash

Maven依赖:spring-boot-starter-data-redis
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Repository类中注入RedisTemplate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Repository
public class CustomerRedisRepository{
//注入RedisTemplate
@Autowired
RedisTemplate<Object, Object> redisTemplate;

//通过名称查找Bean
@Resource(name = "redisTemplate")
//RedisTemplate下操作String的类
ValueOperations<Object, Object> valueOperation;

public void saveCustomer(Customer customer) {
//String类型:set(key, value)
valueOperation.set(customer.getId(), customer);
}

public Customer getCustomer() {
//String类型:get(key)
return (Customer) valueOperation.get("Customer111");
}
}
构建RedisTemplate的代码一般放在Bootstrap
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
@SpringBootApplication
public class RedisApplication{
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}

//构建RedisTemplate
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException{
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
//配置RedisConnectionFactory
redisTemplate.setConnectionFactory(redisConnectionFactory);

//序列化
Jackson2JsonRedisSerializer j2jrs = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
j2jrs.setObjetMapper(om);

redisTemplate.setValueSerializer(j2jrs);
redisTemplate.setKeySerializer(new StringRedisSerializer());

return redisTemplate;
}
}

MongoDB

Maven依赖:spring-boot-starter-data-mongodb
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
实体类
  • @Document表明该类对应MongoDB中的一个文档
  • @Id主键
  • @Field显式声明文档中的字段
1
2
3
4
5
6
7
8
9
10
11
@Document
public class Customer{
@Id
private Long id;
private String firstName;
private String lastName;
private Integer age;

@Field("orders")
private Collection<Order> orders = new LinkedHashSet<Order>();
}
继承MongoRepository接口
1
2
3
4
5
6
public interface CustomerMonoRepository extends MongoRepository<Customer, String> {
List<Customer> findByFirstName(String firstName);

@Query("{'age':?0}")
List<Customer> withQueryFindByAge(Integer age);
}
Controller
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
@RestController
public class CustomerMongoController{
@Autowired
CustomerMongoRepository cr;

@PostMapping("/save")
public Customer save() {
Customer customer = new Customer("yxl", 20);
Collection<Order> orders = new LinkedHashSet<Order>();

Order reactiveMicroservice = new Order("Reactive Microservice In Action", "60");
orders.add(reactiveMicroservice);
customer.setOrders(orders);

return cr.save(customer);
}

@GetMapping("/findByFirstName")
public List<Customer> findByFirstName(String firstName) {
return cr.findByFirstName(firstName);
}

@GetMapping("/withQueryFindByAge")
public List<Customer> withQueryFindByAge(Integer age) {
return cr.withQueryFindByAge(age);
}
}

Spring Reactive Data】:响应式数据访问模型

  • Spring Reactive Data:响应式数据访问模型,包括spring-boot-starter-data-redis-reactivespring-boot-starter-data-mongodb-reactiveCassandraCouchbase……

2.spring-boot-starter-webflux


3.reactor


4.spring-boot-starter-test

  • spring-boot-starter-test:包含JUnitMockitoSpring Boot TestAssertJJSONassertHamcrest等工具在内的测试组件库。
1
2
3
4
5
<dependency>
<groupId>org.springframwork.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

5.Spring Boot Actuator:系统监控组件

Maven依赖

Spring Boot Actuator依赖于Spring HATEOAS

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>

HATEOAS端点

/application:查看所有端点
  • 访问http://localhost:8080/application可以获得所有的HATEOAS端点
应用配置类
  • /autoconfig:获取应用的自动化配置报告,其中包括所有自动化配置的候选项。同时还列出了每个候选项的各个先决条件是否满足,因此,该端点可以帮助我们很方便地找到一些自动化配置为什么没有生效。
  • /configprops:获取应用中配置的属性信息报告。
  • /beans:获取应用上下文中创建的所有Bean以及它们之间的相互关系。
  • /env:获取应用中的所有可用的环境属性报告,包括环境变量、JVM熟悉、应用配置属性、命令行中的参数……
  • /info:返回一些应用自定义的信息。默认情况只返回一个空的JSON串。我们可以在application.properties配置文件中通过info前缀来设置一些属性。
  • /mappings:返回所有Controller映射关系报告,包括beanmethod两个核心属性,bean标识了该映射关系的请求处理器,method标识了该映射关系的具体处理类和处理函数。
度量指标类
  • /metrics:返回当前应用的各类重要度量指标,如内存信息、线程信息、GC信息……
  • /dump:暴露程序运行中的线程信息
  • /health:获取应用的各类健康指标,这些指标信息由HealthIndicator的实现类提供

    如:http://localhost:8080/health,返回如下JOSN

1
2
3
4
5
6
7
8
9
{
"status":"UP",
"diskSpace":{
"status":"UP",
"total":73400315904,
"free":4874935220,
"threshold":10485760
}
}
  • /trace:返回基本的HTTP跟踪信息,包括时间戳和HTTP header
/shutdown:关闭应用程序
  • /shutdown:关闭应用程序,要求endpoints.shutdown.enabled = true

6.Lombok:代码简化工具

Maven依赖

1
2
3
4
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

注解

注解描述
@Getter/@Setter可用作用在类和属性上,放在类上时,会为所有非静态属性生成Getter/Setter;放在属性上,会为该属性生成Getter/Setter
@ToString生成toString(),默认输出类名和所有属性,其中属性按照顺序输出,以,分隔。可以使用exclude属性指定生成的toString()不包括哪些字段,或者使用of属性指定只包含哪些属性
@EqualsAndHashCode默认情况下会使用所有非transient和非static字段生成equals()hashCode()方法,同样有excludeof属性
@NoArgsConstructor无参构造器
@AllArgsConstructor全参构造器
@Slf4j可以不必写private final Logger logger = LoggerFactory.getLogger(XXX.class),每次使用的日志都是LogBack
@Log4j可以不必写private final Logger logger = LoggerFactory.getLogger(XXX.class),每次使用的日志都是log4j
@Data@Getter + @Setter + @ToString + @EqualsAndHashCode

7.Spring Cloud

(1)Spring Cloud Stream

  • spring-cloud-stream
  • spring-cloud-starter-stream-rabbit:引入RabbitMQ作为消息中间件系统
1
2
3
4
5
6
7
8
9
10
11
<!--Spring Cloud Stream-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>

<!--Spring Cloud Stream - Rabbit Binder-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

(2)Spring Cloud Eureka

服务注册中心spring-cloud-starter-netflix-eureka-server
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
客户端spring-cloud-starter-netflix-eureka-client:Producer/Consumer
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

(3)Spring Cloud Hystrix

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

(4)Spring Cloud Gateway

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

(5)Spring Cloud Config

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

(6)Spring Cloud Sleuth

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

8.spring-boot-starter-quartz:定时任务

  • Scheduler将自动配置,并且将自动关联以下Bean:
  1. JobDetail:定义定时任务,可以通过JobBuilder构建;
  2. Calendar
  3. Trigger:定义何时触发定时任务
  • 默认情况使用内存JobStore,但是如果DataSource可用,并且配置了spring.quartz.job-store-type = jdbc,则可以配置基于JDBC的存储。
  • 如果想使用非主DataSource作为定时任务的存储,需要在对应的DataSource类上加@QuartzDataSource注解。
1
2
3
4
5
6
7
8
9
10
11
public class SampleJob extends QuartzJobBean{
private MyService myService;
private String name;
public void setMyService(MyService myService){//...}
public void setName(String name){//...}

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException{
//...
}
}

9.ES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.2</version>
</dependency>

10.百度语音播报SDK

详细应用见Java实现用语音读txt文档》

1
2
3
4
5
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.4.1</version>
</dependency>

11.Spring Doc整合Swagger UI生成文档

1
2
3
4
5
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.1.45</version>
</dependency>
  • 添加完成后,默认访问路径/swagger-ui.html查看图形化文档,如果想自定义路径,修改applicaiton.properties
1
springdoc.swagger-ui.path=/swagger.html

(六)底层原理(常见问题)

1.自动配置是如何实现的?

  1. Spring Boot坚持“约定优于配置”的思想,在应用启动时会通过springboot-starter-autoconfigure引入许多默认的JAR包 —— 在该starter中,针对可能需要的所有依赖(比如web容器、JDBC……)都通过@Configuration进行了配置,根据@Conditional/@ConditionalOnClass/@ConditionalOnMissingClass/@ConditionalOnBean/@ConditionalOnMissingBean/@ConditionalOnProperty/@ConditionalOnResource在满足/不满足某种条件的情况下@Import进不同的配置类,在配置类中创建不同的Bean,交由IoC容器进行采集,所以Spring Boot应用可以在不进行任何额外配置的情况下运行。
  2. 如果想要装配自定义的Bean,则需要使用@Component/@ComponentScan注解进行配置。

2.application.yml文件中的配置属性是如何被读取的?

通过@ConfigurationProperties(prefix = "xxx")注解,可以指定配置属性的前缀,在Spring Boot应用启动时会去application.yml配置文件中查找对应前缀的属性,然后注入给对应的Bean

-------------本文结束感谢您的阅读-------------

本文标题:Spring Boot 2.x

文章作者:DragonBaby308

发布时间:2019年09月24日 - 21:33

最后更新:2020年01月31日 - 21:06

原始链接:http://www.dragonbaby308.com/sb/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%