1. SpringBoot配置及配置文件
一. 引入配置
一般地springboot使用application.properties或application.xml放在classpath目录或者jar所在目录当中,当然也可以变更名字,通过--spring.config.name参数来配置,还可以通过--spring.config.location来指定配置文件路径。事例如下:
java -jar app.jar --spring.config.location=optional:classpath:/default.properties,classpath:/override.properties
其中optional表示可选的,文件如果不存在也没事。
其它设置配置方式:
- 通过系统环境变量,Spring启动的时候会读取系统的环境变量来做为应用的配置。
- 通过System.setProperty设置系统环境变量
- 通过命令行方式,例如java -jar app.jar --name="hello"
- 通过json方式,java -Dsrping.application.json={"name":"test"} -jar app.jar
- 还可以通过spring.config.import引入其它配置文件,例如spring.config.import=optional:file:./dev.properties
二. 读取配置,
1. 一般通过@Value来获取,事例如下:
@Component
public class MyBean {
@Value("${name}")
private String nameame;
}
2. 还可以通过注入Environment对象来通过其中的getProperty方法来读取,事例如下
@Autowired
private Environment environment;
environment.getProperty("name");
3. 通过@ConfigurationProperties注解读取配置到对象当中,事例如下
@Component
@ConfigurationProperties("my.service")
public class MyProperties {
private boolean enabled;
}
相应的配置文件如下:
my.service.enabled=true
还可以通过@EnableConfigurationProperties注解来指定可用的配置类以及@ConfigurationPropertiesScan来扫描特定的包的注解配置类
对于类中的属性firstName来说,配置文件中可以支持几种方式的配置, 例如:first-name, firstName, frist_name
map形式的配置文件如下:
my.map.[key1]=value1
my.map.[key2]=value2
List的对象的配置文件如下
my.list[0].name=test
my.list[0].age=18
springboot还支持Duration, Period等的配置的数据类型,我们来看一看综合实例:
@Component
@ConfigurationProperties("my")
@Data
public class MyConfig {
private String version;
private Map<String, String> mapTest;
private List<MyPojo> listTest;
@DurationUnit(ChronoUnit.SECONDS)
private Duration sessionTimeout;
@PeriodUnit(ChronoUnit.DAYS)
private Period periodTest;
@DataSizeUnit(DataUnit.MEGABYTES)
private DataSize bufferSize;
@Data
public static class MyPojo{
private String name;
private Integer age;
}
}
上面配置类对应的配置文件如下:
my:
version: 1
mapTest:
map:
"[key1]": "value1"
"[key2]": "value2"
listTest:
- name: "张三"
age: 18
- name: "李四"
age: 20
sessionTimeout: 600
periodTest: 1
bufferSize: 2
2. SpringBoot中的Profiles
Spring中的Profiels提供了一个可以根据指定的环境来区分不同的配置文件的一种方式,@Profile注解可以用在@Component, @Configuration,@ConfigurationProperties,来指定特定环境下的生效的配置或Bean。例如:
@Configuration
@Profile("production")
public class ProductionConfiguration{
}
配置文件中配置当中通过spring.profiles.active来申明当前可用的profile. 例如:
spring.profiles.active=dev,mysql
也可以通过命令行的方式来指定,--spring.profiles.active=dev,mysql
申明了有效的profile的后,可以通过application-{profile}.yml的方式来指定特定的配置文件生效。例如:
application-dev.yml
application-mysql.yml
spring.profiles.include可以用来增加当前的可用的配置,例如
spring.profiles.include[0]=common
spring.profiles.include[2]=local
spring.profiles.group可以指定多个生效的profile, 例如
spring.profiles.active=production
spring.profiles.group.production[0]=dev
spring.profiles.group.production[1]=mysql
3. SpringBoot中的logging
SpringBoot提供了Logback, Log4J2, Java Util Logging的三种实现,默认采用了Logback的实现方式。
我们在启动的时候看到的日志如下:
2023-11-23 07:23:20.962 INFO 28351 --- [ main] com.example.MyApplication : Started MyApplication in 2.7 seconds (JVM running for 3.157)
它由下面几部分组成:
2023-11-23 07:23:20.962 : 日期部分
INFO : 日志级别有ERROR, WARN, INFO, DEBUG, TRACE., 默认为INFO
28351: 进程ID
--- : 实际日志内容的分割线
[main]: 线程的名字
com.example.MyApplication: 日志名称,一般是类的史称
Started MyApplication in 2.7 seconds (JVM running for 3.157 : 日志内容
配置文件中可以改变日志的行为,比如变更日志级别:
logging:
group:
tomcat: org.apache.catalina,org.apache.coyote
level:
root: warn
org.springframework.web: debug
tomcat: debug
sql: trace
如上,可以指定具体的日志名称来配置日志级别,也可以定义一个分组,分组内容为类全名,日志级别设定为分组名来定义级别,spring预定义了两个日志分组为web, sql
web: org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sql: org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener
更多配置:
logging.file.name : 指定日志文件的啥名字
logging.file.path: 指定日志文件路径
logback的配置:
配置项 | 描述 |
logging.logback.rollingpolicy.file-name-pattern | 日志存档的文件名格式(默认值:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz) |
logging.logback.rollingpolicy.clean-history-on-start | 应用启动时是否清除以前存档(默认值:false) |
logging.logback.rollingpolicy.max-file-size | 存档前,每个日志文件的最大大小(默认值:10MB) |
logging.logback.rollingpolicy.total-size-cap | 日志文件被删除之前,可以容纳的最大大小(默认值:0B)。设置 1GB 则磁盘存储超过 1GB 日志后就会删除旧日志文件 |
logging.logback.rollingpolicy.max-history | 日志文件保存的最大天数(默认值:7). |
也可以使用logback-spring.xml或者logback.xml来对日志内容进行配置,logback-spring.xml可以使用一些spring的扩展标签引入spring的配置内容,例如来指定特定的环境下配置内容,来使用Environment的配置内容
例如:
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
下面的myapp.fluentd.host为application.properties内配置的内容,可以在xml使用
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
</appender>
日志使用:
1. LoggerFactory 获取Logger对象
private static Logger log = LoggerFactory.getLogger(MyExample.class)
2. 引入 lombok
通过@Slf4j注解来使用,方法内可以直接使用log对象,而无需定义了
日志框架的切换,切换成Log4j2
1. 引入Log4j2的包,并且要排除默认的logging包,否则会有类冲突
<!-- web场景启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除默认日志框架 -->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加log4j2日志框架的场景启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2. 定义log4j2-spring.xml放入classpath内
3. SpringBoot中的异步执行
springboot通过TaskExecutionAutoConfiguration自动配置了线程池ThreadPoolTaskExecutor, 线程池的参数可以通过TaskExecutionProperties这个类来配置,例如:
spring.task.execution.pool.coreSize
spring.task.execution.pool.maxSize
spring.task.execution.pool.queueCapacity
应用开发当中可以直接通过ThreadPoolTaskExecutor注入使用
项目当中也可以定义多个Executor, 不同的方法使用不同的Executor来执行。例如:
@Configuration
public class MyConfiguration{
@Bean
public Executor exchangeCodeExecutor(){
ThreadPoolTaskExecutor exeutor = new ThreadPoolTaskExecutor()
exector.setCorePoolSize(2);
....
return executor;
}
}
在方法上使用@Async注解指定线程池名称
@Async("exchangeCodeExecutor")
public void asyncGenerateCode(Coupon coupon){
}
使用异步方法的前提是在启动类上增加@EnableAsync
4. SpringBoot中的定时任务
- 在启动类上使用@EnableScheduling开启定时任务
- 通过@Scheduled来定义定时任务
@Component
public class MyScheduledTask {
@Scheduled(fixedRate = 5000)
public void executeTask() {
System.out.println("Fixed rate task executed at " + System.currentTimeMillis());
}
}
@Scheduled(fixedDelay = 5000) 表示任务在上一个任务完成后的 5 秒后执行
@Scheduled(cron = "0 0/1 * * * ?") 表示每分钟的开始执行任务
自定义定时任务线程池
@Configuration
public class SchedulingConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10); // 设置线程池大小
scheduler.setThreadNamePrefix("scheduled-task-");
return scheduler;
}
}
5. SpringBoot中自定义starter
1. 自定义AutoConfiguration
@Configuration // 模式注解装配
@EnableHelloWorldConfiguration // @Enable模块装配,这个装配是会生成一个helloWorldBean的
public class HelloWorldAutoConfiguration {
}
2. 定义@EnableHelloWorldConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HelloWorldConfiguration.class)
public @interface EnableHelloWorldConfiguration {
}
3. 定义HelloWorldConfiguration
public class HelloWorldConfiguration {
@Bean
public String helloWorld() {
return "hello World!";
}
}
4. 在resources目录下新建META-INF文件夹,在下面新建spring.factories文件,在这里面进行配置,将EnableHelloWorldConfiguration绑定给@EnableAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.imooc.study.configration.HelloWorldAutoConfiguration
Spring提供了一系列的Conditional,可以灵活控制Bean是否生效,常用的Conditional如下:
- @ConditionalOnBean:容器中存在指定Bean
- @ConditionalOnMissingBean :容器中不存在指定Bean
- @ConditionalOnProperty:系统中指定的属性是否有指定的值
- @ConditionalOnClass :系统中有指定的类
- @ConditionalOnMissingClass: 系统中没有指定的类
- @ConditionalOnExpression :满足SpEL表达式指定
- @ConditionalOnSingleCandidate :容器中只有一个指定的Bean,或者这个Bean是首选Bean
- @ConditionalOnResource :类路径下是否存在指定资源文件
- @ConditionalOnWebApplication :当前是web环境
- @ConditionalOnNotWebApplication :当前不是web环境
- @ConditionalOnJava:系统的java版本是否符合要求
事例,定义一个DbTemplateAutoConfiguration
@Configuration
@Slf4j
@EnableConfigurationProperties(DbProperties.class)
@ConditionalOnProperty(name="db.db-template-enabled",havingValue = "true")
public class DbTemplateAutoConfiguration {
@Autowired
private DbProperties dbProperties;
@Bean
@ConditionalOnMissingBean(value= DbTemplate.class)
public DbTemplate dbTemplate(){
DbTemplate dbTemplate = new DbTemplate(new QueryRunner(),dataSource());
return dbTemplate;
}
@Bean
@ConditionalOnMissingBean(value= DataSource.class)
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(dbProperties.getDriverClassName());
dataSource.setUrl(dbProperties.getUrl());
dataSource.setUsername(dbProperties.getUsername());
dataSource.setPassword(dbProperties.getPassword());
return dataSource;
}
}
定义DbProperties
@ConfigurationProperties(prefix = "db")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DbProperties {
/**
* if you want to use a dbTempate to operate datasouce,dbTemplateEnabled must be true,default false
*/
private boolean dbTemplateEnabled = false;
/**
* jdbc driverClassName must can not be null
*/
private String driverClassName;
/**
* datasource password must can not be null
*/
private String password;
/**
* datasource username must can not be null
*/
private String username;
/**
* datasource url must can not be null
*/
private String url;
}
spring.factories配置如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.github.lybgeek.autoconfigure.dbtemplate.DbTemplateAutoConfiguration
打包一成一个db-template-spring-boot-starter的jar包
在另一个项目引用这个db-template-spring-boot-starter jar包,这样在配置文件application.properties里配置如下,DbTemplate就会生效
db.db-template-enabled=true
db.driver-class-name=xxx
db.username=xxx
db.password=xxx
db.url=xxx