Spring Boot 提供了一种统一的方式来管理应用的配置,允许开发人员使用属性properties文件、YAML 文件、环境变量和命令行参数来定义优先级不同的配置值。零XML配置的Spring Boot Application,是基于Spring JavaConfig。
Spring放弃XML配置简史
Spring IOC有一个非常核心的概念——Bean。由Spring容器来负责对Bean的实例化,装配和管理。最早XML是用来描述Bean最为流行的配置方式。Spring可以从XML配置文件中读取任何类型的元数据并自动转换成相应的Java代码。随着Spring的日益发展,越来越多的人对Spring提出了批评。“Spring项目大量的烂用XML”就是最为严励的一个批评。
由于Spring会把几乎所有的业务类都以Bean的形式配置在XML文件中,造成了大量的XML文件。使用XML来配置Bean失去了编译时的类型安全检查。大量的XML配置使得整个项目变得更加复杂。我们使用XML配置的问题之一是要等到运行时的时候来发现Bean里面的错误或者其他愚蠢的问题。当然,在使用Spring的IDE插件(或者其他整合了Spring Tools Suite的工具)能在一定程度上发现这方面问题。
- Spring 2.5中我们开始有了面向注解的依赖注入编程(@Component和 @Autowired)。
- Spring 3.0中我们有了 JavaConfig , 它能够取代 XML。Spring 3.1中又提供了@Enable* 系列的注解,使得基于注解的配置更加自动化。
- 在 Spring 4.0中@Conditional注解(org.springframework.context.annotation.Conditional)实现的基于条件的配置,根据应用的类路径中的类、环境信息以及其他一些相关信息,在运行时自动化地完成配置,大量省去了程序员们大量样板化的手工配置工作。
要进一步解决的问题
在有了上面的这些支持后,使用Spring或者SpringMVC的过程中,仍然有很多配置以及繁琐的操作需要我们手工去完成。例如:
- 单独部署配置一个 tomcat(tomcat 的相关配置需要单独去tomcat安装目录下配)
- 使用大量依赖库可能导致的版本冲突
- Spring 集成使用使用模板引擎 Freemarker、velocity、thymeleaf 等需要单独配置
- Spring 集成使用 MyBatis、JPA 等 ORM 框架需要单独配置
- Spring 集成使用安全框架 Security 、日志框架等等都需要单独一套配置
- 配置 SpringMVC 中的 DispatcherServlet 需要在 web.xml 或者在 Servlet 初始化代码里进行显式配置
- 静态资源的处理
- 应用的运维监控工作等
由于这些已经存在的问题,Spring Boot应运而生,使用Spring Boot可以让我们快速创建一个基于Spring的项目,而让这个Spring项目跑起来我们只需要很少的配置就可以了。
SpringBoot 的核心功能
Spring Boot主要有如下核心功能:
- 直接创建一个可以独立运行的Spring项目
Spring Boot可以以jar包的形式来运行,我们可以直接通过 java -jar xx.jar 命令来运行一个Spring Boot项目。
- 内嵌Servlet容器
Spring Boot可以内嵌Tomcat直接一键运行 Web 应用。我们不再需要打 war 包,丢到 Tomcat 下面,再启动 Tomcat 等等一系列操作了。
提供starter简化 Maven/Gradle 配置
使用Spring或者SpringMVC我们需要添加大量的依赖,而这些依赖很多都是固定的样板化配置。Spring Boot 通过starter 帮助我们简化 Maven/Gradle 配置。
-
- 自动配置Spring
SpringBoot 提供了大量超级实用的 starter,大大简化了我们使用 Spring 开发过程中的配置。
-
- 生产环境的应用监控
使用SpringBoot 提供的 Actuator ,我们可以方便地进行应用程序的监控。
-
- 无代码生成和xml配置
SpringBoot 没有引入任何形式的代码生成,它是使用的 Spring 4.0的条件注解以实现根据条件进行配置;同时使用了 Maven/Gradle 的依赖传递解析机制来实现 Spring 应用里面的自动配置。
回顾 Spring
Spring能够进行自动化的装配,它使用两种方式来进行自动化装配:
1、组件扫描:Spring会自动发现应用上下文中所创建的bean
2、自动装配:Spring会自动构建bean之间的依赖关系
Spring的自动化装配使用了零xml配置,也就是使用了全代码配置(注解配置),其中代码配置类使用@Configuration注解进行标注。
1、组件扫描:
@Component能给一个类自动生成对象并注入到Spring容器中,比如下面的CDPlayer,会自动new一个CDPlayer的对象并放置到Spring容器中。
public interface Player {
void play();
}
@Component
public class CDPlayer implements Player {
public void play() {
System.out.print("播放CD");
}
}
我们知道,Spring容器中每个bean都有自己唯一的一个id,自动注入的bean的id的规则如下:
1、如果@Component中有值,类似@Compoent("xxx"),那么此bean的id即为xxx 。
2、如果类名为第一个字母大写,第二个字母小写,即满足首字母大写的驼峰命令规则,比如CdPlayer, 那么其bean的id第一个字母要小写,其余不变,所以最终为cdplayer。
3、如果不满足规则1,比如类名是CDPlayer, 那么其bean的id跟类名相同,所以最终为CDPlayer。
2、自动装配
需要注意的是,配置对象需要 @Configuration和@ComponentScan注解,而@ComponentScan注解是标注Spring扫描的基础包名的。如果没有值,默认会扫描自己所在的包的所有类。
其中的Configuration配置对象:
@Configuration
@ComponentScan
public class PlayerConfig {
}
那么如何配置扫描包呢?比如我想扫描 com.easy.springboot 包下的所有类,可以这样:
@ComponentScan(basePackages = "com.easy.springboot")
我们使用junit4来进行测试,注意在想获取Spring中bean上加上@Autowired,Spring会自动注入。另外,下面的Player可以换成CDPlayer,因为CDPlayer的对象既是CDPlayer的对象,也是Player的对象。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = PlayerConfig.class)
public class TestCDPlayer {
@Autowired
private Player cdPlayer;
@Test
public void testNotNull(){
cdPlayer.play();
}
}
另外,我们也可以将一个对象注入到另一个对象中。比如有一个People类,要为其注入一个Player类,然后其跑步的时候会调用Player类的play方法,这样实现即可:
@Component
public class People {
@Autowired
private Player player;
public void run(){
player.play();
System.out.println("正在跑步");
}
}
这里的
@Autowired
private Player player
Spring会自动把生成的Player对象注入到People类中。
注入的规则分为两步:
1、Spring会先查找id为player的Bean对象,如果找到,注入进来
2、如果没有找到id为player的Player对象,那么就去寻找Spring容器中查找Player的对象,如果一个都没有,或者有两个或者多个,那么就会报错。
3、使用用JavaConfig
一般来说,自动装配bean已经能为我们解决很多问题。但是,有的时候可能我们需要更自动的配置,这个时候我们就可以使用 JavaConfig 来完成。
Spring Boot的零XML配置也是基于 JavaConfig来实现的。
JavaConfig就是使用注释来描述Bean配置的组件,也就是注解驱动配置( Annotation-Driven Configuration)。它是从Spring 3.0后嵌入到Spring里的一个以前的独立项目。JavaConfig能够等价看成是XML文件,不过它只是用Java编写的。
提示:JavaConfig 是Spring的一个子项目(详细了解可参考:http://docs.spring.io/spring-javaconfig/docs/).
比如我想获取同一个类的多个bean对象,就可以在JavaConfig中声明方法来装配bean:
@Bean
public Player player(){
return new CDPlayer();
}
此时Spring容器就会生成一个Player的对象,其id为player(注意id与方法名是一样的)。我们也可以为Player对象指定Bean id:
@Bean(name="firstPlayer")
public Player player(){
return new CDPlayer();
}
那么我们在代码中就可以根据这个id名称来装配这个 Bean
@Autowired
private Player firstPlayer
不过,要注意的是@Autowired默认按类型(byType)装配。如果我们想使用名称装配,可以结合@Qualifier注解进行使用,如下:
@Autowired
@Qualifier("firstPlayer")
private Player firstPlayer;
另外,我们还可以使用@Resource(这个注解属于J2EE的)
@Resource(name="firstPlayer") //在字段上的注入,先按照名字装配
private Player firstPlayer;
默认按照名称(byName)进行装配,名称可以通过name属性进行指定, 装配规则是:
1、如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。
2、当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
Spring的XML配置方式是使用被Spring命名空间的所支持的一系列的XML标签来实现的。Spring有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc等。
使用XML来配置Bean所能实现的功能,通过JavaConfig同样可以很好的实现。之前我们都是在xml文件中定义bean的,比如:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloBean" class="com.hello.impl.HelloWorldImpl">
</beans>
其实我们可以使用注解来完成这些事情,例如下面的代码,完成的功能和上面的xml配置的功能是一样的:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.hello.HelloWorld;
import com.hello.impl.HelloWorldImpl;
@Configuration
public class AppConfig {
@Bean(name="helloBean")
public HelloWorld helloWorld() {
return new HelloWorldImpl();
}
}
使用@Bean注解,来标识此方法构造出一个由Spring容器管理的bean。@Bean声明所起到的作用与<bean/> 元素类似。
Spring对Java配置的支持是由@Configuration注解和@Bean注解来实现的。由@Bean注解的方法将会实例化、配置和初始化一个新对象,这个对象将由Spring的IoC容器来管理。
4、导入子配置类
其实,Spring 中的 XML 配置文件本质上说是一种编程元数据。在早期Java版本中,应用中的元数据一般使用属性文件、XML。但是用配置文件不够灵活而且比较繁琐。从Spring 3起,JavaConfig功能已经包含在Spring核心模块,它允许开发者将bean定义和在Spring配置XML文件到Java类中。与此同时仍然允许使用经典的XML方式来定义bean和配置。
一般在一个大型工程项目中,如果将所有的bean都配置在一个xml文件中,那么这个文件就会非常的大。所以一般会将一个大的xml配置文件分割为好几份。这样方便管理,最后在总的那个xml文件中导入。比如:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<import resource="config/customer.xml"/>
<import resource="config/scheduler.xml"/>
</beans>
但是现在我们也可以使用JavaConfig来完成同样的工作了:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ CustomerConfig.class, SchedulerConfig.class })
public class AppConfig {
}
@Configuration可以被认为是相当于XML的< bean / >元素。
5、导入XML 配置
在 Spring XML中, 启动注解注入bean,通过如下标签实现:
<context:annotation-config/>
在 JavaConfig中, 等同于 @AnnotationDrivenConfig注解。 代码示例:
@Configuration
@AnnotationDrivenConfig
public class Config {
}
使用@ComponentScan注解,等同于在 Spring XML中的
<context:component-scan/>
代码示例:
package com.company.foo;
@Service
public class FooServiceImpl implements FooService {
private final FooRepository fooRepository;
@Autowired
public FooService(FooRepository fooRepository) {
this.fooRepository = fooRepository;
}
// ...
}
package com.company.foo;
@Repository
public class JdbcFooRepository implements FooRepository {
private final DataSource dataSource;
@Autowired
public FooRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
// ...
}
@Configuration
@ComponentScan("com.company") // search the com.company package for @Component classes
@ImportXml("classpath:com/company/data-access-config.xml") // XML with DataSource bean
public class Config {
}
在配置类中使用上述的配置,我们就可以在代码里调用service方法了:
public class Main {
public static void main(String[] args) {
JavaConfigApplicationContext ctx = new JavaConfigApplicationContext(Config.class);
FooService fooService = ctx.getBean(FooService.class);
fooService.doStuff();
}
}
一、 application.properties
默认的服务端口是8080,那么如何在配置文件application.properties设置服务端口呢?
很简单。SpringBootApplication有个系统级的配置文件application.properties
我们只需要在里面加一行配置即可:
server.port=5678
启动应用,我们将在日志信息中看到:
2017-04-04 23:31:21.673 INFO 90250 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-04-04 23:31:21.774 INFO 90250 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 5678 (http)
2017-04-04 23:31:21.780 INFO 90250 --- [ main] com.example.DemoApplication : Started DemoApplication in 4.712 seconds (JVM running for 5.511)
TomcatEmbeddedServletContainer已经在5678端口监听请求了。
浏览器访问:http://localhost:5678/hello
你会看到成功输出:
Hello World! Tue Apr 04 23:32:38 CST 2017
application.properties是Spring Boot约定的配置文件。Spring Boot基于这个配置文件的配置机制充分体现了Spring Boot遵循的“约定优于配置”的原则。
Spring Boot几乎所有的配置项都可以在这个文件中配置,如果不配置,则使用默认项。Spring Boot会检测配置项的key,启动相应的自动配置模块。
下面具体介绍一些在application.properties配置中的特性和使用方法。
1.数据源datasource配置
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
当Spring Boot一旦检测到数据库配置相关的配置项(spring.datasoure.*),Spring Boot会自动根据相应的配置项,建立数据库连接池。
这个application.properties里面到底有哪些key是可配置的呢?在SpringBoot官网文档给出了详尽的配置以及说明。在Appendix A. Common application properties中: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#common-application-properties
不完全统计,这个完整的application properties文件,有1183行。其中,属性key有950个。当你看到如此庞大的配置,你一定会被吓到。不过,在实际项目中,我们如果遵循Spring Boot的约定,通常不需要我们单独指定太多配置。
虽然是零XML配置,但是“有些配置的事情”,还是必须要做的。这里SpringBoot的实现方案,充分体现了Spring框架的“约定优于配置”理念。通过约定俗成的规范,很多问题的解决讲得到大大的简化。
2.在application.properties自定义属性与加载
我们可以将自己自定义的属性配置在application.properties中(注意不要和Spring Boot的默认配置的key重复),然后在java类中通过@Value("${属性名}")注解来加载对应的配置属性,例如:application.properties文件中有如下自定义配置项:
com.easy.springboot.h5perf.app.name = H5性能测试平台
则在java中有如下应用:
1 @Component
2 public class TestProperties {
3 @Value("${com.easy.springboot.h5perf.app.name }")
4 private String appName;
5 }
3.配置项值的引用
在application.properties中的各个参数之间可以直接通过“${keyname}”引用来使用。
在application.properties中也可以通过“@keyname@”来引用pom文件中的元素节点值,例如:
pom文件中有如下定义:
<properties>
<project.name>easy-springboot-demo </ project.name >
<project.version>1.0</ project.version >
</properties>
则在application.properties文件中可以通过如下方式引用:
# 项目名称
com.easy.springboot.project.name = @project.name@
# 项目版本
com.easy.springboot.project.version = @project.version@
4.随机数属性value
在一些情况下,有些参数我们需要希望它不是一个固定的值,Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。
例如:
# 随机字符串
com.easy.springboot.string=${random.value}
# 随机int
com.easy.springboot.number=${random.int}
# 随机long
com.easy.springboot.bignumber=${random.long}
# 100以内的随机数
com.easy.springboot.range1=${random.int(100)}
# 100-200的随机数
com.easy.springboot.range2=${random.int[100,200]}
- 属性配置文件的位置
spring会从classpath下的/config目录或者classpath的根目录查找application.properties或application.yml。
/config优先于classpath根目录。
二、 Spring Boot属性配置和使用
一般在一个项目中,总是会有好多个环境。比如:开发环境 -> 测试环境 -> 预发布环境 -> 生产环境
在应用中管理配置是一个重要的问题,尤其是在应用需要部署到多个环境中时。通常会需要为每个环境提供一个对应的属性文件,用来配置各自的数据库连接信息、服务器信息和第三方服务账号等。通常的应用部署会包含开发、测试和生产等若干个环境。
常规情况下,我们都知道Spring Boot的配置会从application.properties中读取。实际上,从resource目录下的application.properties文件读取是Spring Boot配置链中的一环而已。
2.1、配置的优先级
Spring Boot提供了一种优先级配置读取的机制来帮助我们从这种困境中走出来。
Spring Boot 所提供的配置优先级顺序比较复杂。按照优先级从高到低的顺序,具体的列表(从高到低)如下所示。
1.命令行参数(优先级最高)。
2.通过 System.getProperties() 获取的 Java 系统参数。
3.操作系统环境变量。
4.从java:comp/env 得到的JNDI 属性。
5.通过 RandomValuePropertySource 生成的random.*属性。
6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件,通过spring.config.location参数指定
7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件
9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件
10.应用 Java配置类,包含@Configuration注解的 Java 类,通过@PropertySource注解声明的属性文件。
11.通过SpringApplication.setDefaultProperties声明的默认属性。
如果Spring Boot在优先级更高的位置找到了配置,那么它就会忽略优先级低的配置。下面我们简单讲讲这些优先级。
2.2、命令行参数配置
Spring Boot 的这个配置优先级看似复杂,其实是很合理的。命令行参数的优先级之所以被设置为最高,是因为可以方便我们在测试或生产环境中快速地修改配置参数值,而不需要重新打包和部署应用。
SpringApplication 类默认会把以“--”开头的命令行参数转化成应用中可以使用的配置参数,如 “--name=Alex” 会设置配置参数 “name” 的值为 “Alex”。
如果不需要这个功能,可以通过:
SpringApplication.setAddCommandLineProperties(false)
禁用解析命令行参数。
2.3、 random.*属性配置
RandomValuePropertySource 可以用来生成测试所需要的各种不同类型的随机值,从而免去了在代码中生成的麻烦。RandomValuePropertySource 可以生成数字和字符串。数字的类型包含 int 和 long,可以限定数字的大小范围。以“random.”作为前缀的配置属性名称由 RandomValuePropertySource 来生成,代码示例:
user.id=${random.value}
user.count=${random.int}
user.max=${random.long}
user.number=${random.int(100)}
user.range=${random.int[100, 1000]}
2.4、属性文件配置
属性文件是最常见的管理配置属性的方式。Spring Boot 提供的 SpringApplication 类会搜索并加载 application.properties 文件来获取配置属性值。SpringApplication 类会在下面位置搜索该文件:
1.当前目录的/config子目录
2.当前目录
3.classpath中的/config包
4.classpath
上面的顺序也表示了该位置上包含的属性文件的优先级。优先级按照从高到低的顺序排列。
可以通过spring.config.name这个key的配置属性来指定不同的属性文件名称。也可以通过spring.config.location来添加额外的属性文件的搜索路径。
对于配置属性,可以在代码中通过“@Value”来使用,例如:
@RestController
@EnableAutoConfiguration
public class Application {
@Value("${name}")
private String name;
@RequestMapping("/")
String home() {
return String.format("Hello %s!", name);
}
}
其中,@Value("${name}")注解的意思就是,变量 name 的值来自配置属性中的name属性。
2.5、 YAML格式的配置文件
相对于属性文件来说,YAML 是一个更好的配置文件格式。当有前缀的情况下,使用.yml格式的配置文件更简单。
注意:使用.yml时,属性名的值和冒号中间必须有空格,如name: SpringBoot正确,SpringBoot就是错的。
YAML 在 Ruby on Rails 中得到了很好的应用。YAML是JSON的一个超集,也是一种方便的定义层次配置数据的格式。它的基本语法规则如下:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- # 表示注释,从这个字符一直到行尾,都会被解析器忽略。
只要你将SnakeYAML 库放到classpath下,SpringApplication就会自动支持YAML,以作为properties的替换。当然,我们通常不需要这么做,因为我们一般都会使用Starters,在spring-boot-starter里会自动加载SnakeYAML。
Spring框架提供两个便利的类用于加载YAML文档,YamlPropertiesFactoryBean会将YAML加载为Properties,YamlMapFactoryBean会将YAML加载为Map。
Spring Boot使用application.properties默认了很多配置。但需要自己添加一些配置的时候,我们应该怎么做呢。
例如,下面这段yml格式的配置
environments:
dev:
url: http://dev.easy.springboot.com
name: Easy Spring Boot
会转化为:
environments.url=http://dev.easy.springboot.com
environments.name=Easy Spring Boot
如果我们自定义了属性key,在代码中怎样使用上面的配置信息呢?利用Spring DataBinder工具集,Spring Boot通过注解@ConfigurationProperties 和@EnableConfigurationProperties 来完成这件事情。
在代码中对应的Bean对象:
@ConfigurationProperties(prefix="environments")
public class EnvironmentsConfig {
private String url;
private String name;
public String getUrl(){ return this.url; }
public void setUrl(String url){ this.url = url; }
public String getName(){ return this.name; }
public void setName(){ this.name = name; }
}
有些时候,我们还会配置类似下面这样的列表的属性
my:
servers:
- dev1.easy.com
- dev2.easy.com
会转化为:
my.servers[0]=dev1.easy.com
my.servers[1]=dev2.easy.com
使用@ConfigurationProperties这个注解来实现属性Bean的绑定,需要在Bean里面添加一个java.util.List(或者Set)类型的属性,然后写好setter(setter也可以换成初始化一个对象),getter:
@ConfigurationProperties(prefix="my")
public class ServersConfig {
private List<String> servers = new ArrayList<String>();//initialize it with a mutable value, equals a setter
public List<String> getServers() {
return this.servers;
}
}
因为YamlPropertySourceLoader类能够将YAML作为PropertySource导出到Spring Environment。所以我们可以使用常用的@Value注解配合占位符语法访问YAML属性。
另外,当我们使用@ConfigurationProperties注解定义配置的Bean时,需要在SpringBoot Application启动类上标注@EnableConfigurationProperties。
2.6、使用 Java配置类
Spring 框架本身提供了多种的方式来管理配置属性文件。Spring 3.1 之前可以使用 PropertyPlaceholderConfigurer。Spring 3.1 引入了新的环境(Environment)和概要信息(Profile)API,是一种更加灵活的处理不同环境和配置文件的方式。
Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只在特定的环境下生效。任何@Component或@Configuration都能注解@Profile,从而限制加载它的环境:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
指定的属性方式常用的有2种:
- 配置在application.properties中:
spring.profiles.active=production
- 或使用命令行开关:
--spring.profiles.active=production
如果应用中包含多个 profile,可以为每个 profile 定义各自的属性文件,按照application-{profile}.properties(.yml)来命名。
三、使用CommandLineRunner执行初始化加载
实际应用中,有时候我们在项目服务启动的时候就去加载一些数据或做一些事情这样的需求。 以前比较常见的做法是写再static代码块中。
在Spring Boot中,它提供了一个CommandLineRunner接口,实现这个接口的类总是会被优先启动,并优先执行CommandLineRunner接口中提供的run()方法。例如
public class ApplicationConfigure implements CommandLineRunner {
@Override
public void run(String... strings) throws Exception {
//TODO : 比如说,在这里预先加载的一些方法,类,属性等。
}
}
如果有多个CommandLineRunner接口实现类,那么可以通过注解@Order来规定所有实现类的运行顺序。
小结
Spring Boot 它抛弃了Spring 中繁琐的xml配置文件的方式,声明式注解的方法为服务开发提供快速简洁的配置方式。在Spring Boot 中,我们会发现,我们其实不用做一些基本的配置也能直接运行刚创建好的工程项目,因为它内嵌了很多基本的通用的配置组件而不需要我们自己来做一些重复的配置工作。