SpringBoot2.0版本對於配置檔案的讀取
@ConfigurationProperties 2.0已不支援,雖然編譯通過,但是IDEA會有個錯誤提示
提示為Spring Boot Configuration Annotation Processor not found in classpath
我為了解決這個提示 查了好多資料 但是都是SpringBoot1.5版本或更低的版本用spring-boot-configuration-processor
來解決,官方文件上也沒給出demo,最後忘記在哪個網站上找到
通過ApplicationContext
上下文獲取Environment
,再通過Binder
獲取配置檔案的方法,再查詢Environment
而即使你引入了processor
jar包 並下載下來了,但pom.xml還是會報一個錯誤
Failed to read artifact descriptor for org.springframework.boot:spring-boot-configuration-processor:jar:2.0.4.RELEASE less... (Ctrl+F1)
Inspection info: Inspects a Maven model for resolution problems.
<dependency>
<groupId >org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
package com.pbh.springbootdemo;
//import org.mybatis.spring.annotation.MapperScan;
//import com.pbh .springbootdemo.properties.datasource.ReadDataSourceProperties;
import com.pbh.springbootdemo.properties.datasource.ReadDataSourceProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.boot.context.properties.bind.Bindable;
//import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
//@MapperScan("com.pbh.springbootdemo.mapper")
public class SpringbootdemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(SpringbootdemoApplication.class, args);
Binder binder = Binder.get(context.getEnvironment()); //繫結簡單配置
ReadDataSourceProperties foo = binder.bind("spring.read", Bindable.of(ReadDataSourceProperties.class)).get();
//ReadDataSourceProperties readDataSourceProperties = binder.bind("spring.read",ReadDataSourceProperties.class).get();
System.out.println(foo.getUrl());
}
}
@PropertySource 用於標識自定義配置檔案位置 如果是application.yml(application.properties) 可以不用,因為SpringBoot 會自動掃描application.yml(application.properties)
@Component 標識此class為元件 用於自動注入 但2.0不需要自動注入 所以不用
屬性名稱的對應 driverClassName 對應 yml(xml)裡的 driver-class-name
SpringBoot建議以小寫字母
+-
+ 小寫字母
的方式在xml或yml中命名屬性
配置檔案class
package com.pbh.springbootdemo.properties.datasource;
//import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
//import org.springframework.stereotype.Component;
/**
* @ClassName MasterDataSourceProperties
* @Descrition 主庫資料庫配置
* @Author pbh
* @Date 2018/9/3 11:17
* @Version 1.0
**/
//@Component
@PropertySource("classpath:application.yml")
//@ConfigurationProperties(prefix = "spring.master")
public class MasterDataSourceProperties {
private String url;
private String username;
private String password;
private String driverClassName;
private String type;
private int maxActive;
private int initialSize;
private int minIdle;
private long maxWait;
private int timeBetweenEvictionRunsMillis;
private long minEvictableIdleTimeMillis;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
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 getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
}
建議使用yml方式配置屬性檔案,IDEA 對於yml檔案有自動提示很友好(自定義的除外),看起來很清爽,以後會慢慢代替xml成為一種趨勢
application.yml
一定要注意各個層次 否則很容易程式報錯
server:
port: 8080
spring:
application:
name: springbootdemo
aop: proxy-target-class=false
#datasource:
#name: test
#type: com.alibaba.druid.pool.DruidDataSource
#druid相關配置
#druid:
#監控統計攔截的filters
#filters: stat
#driver-class-name: com.mysql.jdbc.Driver
#基本屬性
#url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
#username: root
#password: root
#配置初始化大小/最小/最大
#initial-size: 1
#min-idle: 1
#max-active: 20
#獲取連線等待超時時間
#max-wait: 60000
#間隔多久進行一次檢測,檢測需要關閉的空閒連線
#time-between-eviction-runs-millis: 60000
#一個連線在池中最小生存的時間
#min-evictable-idle-time-millis: 300000
#validation-query: SELECT 'x'
#test-while-idle: true
#test-on-borrow: false
#test-on-return: false
#開啟PSCache,並指定每個連線上PSCache的大小。oracle設為true,mysql設為false。分庫分表較多推薦設定為false
#pool-prepared-statements: false
#max-pool-prepared-statement-per-connection-size: 20
#讀寫分離配置
master: #主庫 擁有讀寫許可權
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&emptyStringsConvertToZero=true
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
max-active: 20
initial-size: 1
min-idle: 3
max-wait: 600
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
read: #從庫 擁有讀許可權
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&emptyStringsConvertToZero=true
username: read
password: root123
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
max-active: 20
initial-size: 1
min-idle: 3
max-wait: 600
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
swagger:
enabled: true #是否開啟
title: swagger demo #標題
description: spring boot demo #描述
version: 1.0.0 #版本
base-package: com.pbh.springbootdemo.controller #swagger掃描的基礎包,預設:全掃描(分組情況下此處可不配置)
#定義的api的字首,必須已/開頭,測試用例的主機則為:host+bashPath
#basePath: /api
contact: #維護者資訊
name: pbh,xjl #名字
#全域性引數,比如Token之類的驗證資訊可以全域性話配置
#global-operation-parameters:
#description: 'Token資訊,必填項'
#modelRef: 'string'
#name: 'Authorization'
#parameter-type: 'header'
#required: true
#groups:
#basic-group:
#base-package: com.battcn.controller.basic
#system-group:
#base-package: com.battcn.controller.system
security:
username: admin
password: admin
filter-plugin: false #開啟登入
validator-plugin: false #是否開啟Bean 驗證外掛 預設false
## 該配置節點為獨立的節點,有很多同學容易將這個配置放在spring的節點下,導致配置無法被識別
#mybatis:
#mapper-locations: classpath:mapping/*.xml #注意:一定要對應mapper對映xml檔案的所在路徑
#type-aliases-package: com.pbh.model # 注意:對應實體類的路徑
#分頁
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
returnPageInfo: check
#配置sql日誌
logging:
level:
com.pbh.springbootdemo.mapper: debug # 改成你的mapper檔案所在包路徑(debug級別只比trace低)
讀取配置檔案class
這裡使用自動注入Environment
然後使用SpringBoot 推薦的Binder讀取配置檔案
Binder binder = Binder.get(environment); //繫結簡單配置
this.readDataSourceProperties = binder.bind("spring.read", Bindable.of(ReadDataSourceProperties.class)).get();
this.masterDataSourceProperties = binder.bind("spring.master",Bindable.of(MasterDataSourceProperties.class)).get();
package com.pbh.springbootdemo.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.pbh.springbootdemo.properties.datasource.MasterDataSourceProperties;
import com.pbh.springbootdemo.properties.datasource.ReadDataSourceProperties;
//import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.EnvironmentAware;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
//import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
//import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//import org.springframework.core.env.Environment;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName DataBaseConfiguration
* @Descrition Druid的DataResource配置類
* @Author PanBaihui
* @Date 2018/9/3 10:46
* @Version 1.0
**/
@Configuration
@EnableTransactionManagement
public class DataBaseConfiguration {
@Autowired
private Environment environment;
private MasterDataSourceProperties masterDataSourceProperties;
private ReadDataSourceProperties readDataSourceProperties;
public DataBaseConfiguration(){
System.out.println("----------- DataBaseConfigurationStart -----------");
}
public void setProperties() {
Binder binder = Binder.get(environment); //繫結簡單配置
this.readDataSourceProperties = binder.bind("spring.read", Bindable.of(ReadDataSourceProperties.class)).get();
this.masterDataSourceProperties = binder.bind("spring.master",Bindable.of(MasterDataSourceProperties.class)).get();
}
public DataSource master() {
System.out.println("注入Master資料來源!!!");
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(masterDataSourceProperties.getUrl());
datasource.setDriverClassName(masterDataSourceProperties.getDriverClassName());
datasource.setUsername(masterDataSourceProperties.getUsername());
datasource.setPassword(masterDataSourceProperties.getPassword());
datasource.setInitialSize(masterDataSourceProperties.getInitialSize());
datasource.setMinIdle(masterDataSourceProperties.getMinIdle());
datasource.setMaxWait(masterDataSourceProperties.getMaxWait());
datasource.setMaxActive(masterDataSourceProperties.getMaxActive());
datasource.setMinEvictableIdleTimeMillis(masterDataSourceProperties.getMinEvictableIdleTimeMillis());
try {
datasource.setFilters("stat,wall");
} catch (SQLException e) {
e.printStackTrace();
}
return datasource;
}
public DataSource read() {
System.out.println("注入Read資料來源!!!");
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(readDataSourceProperties.getUrl());
datasource.setDriverClassName(readDataSourceProperties.getDriverClassName());
datasource.setUsername(readDataSourceProperties.getUsername());
datasource.setPassword(readDataSourceProperties.getPassword());
datasource.setInitialSize(readDataSourceProperties.getInitialSize());
datasource.setMinIdle(readDataSourceProperties.getMinIdle());
datasource.setMaxWait(readDataSourceProperties.getMaxWait());
datasource.setMaxActive(readDataSourceProperties.getMaxActive());
datasource.setMinEvictableIdleTimeMillis(readDataSourceProperties.getMinEvictableIdleTimeMillis());
try {
datasource.setFilters("stat,wall");
} catch (SQLException e) {
e.printStackTrace();
}
return datasource;
}
@Bean
public DynamicDataSource dynamicDataSource() {
//主動例項化主庫和讀庫資料來源
//為了防止spring注入異常,所以master和read都是主動例項化的,並不是交給spring管理
this.setProperties();
DataSource master = master();
DataSource read = read();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DynamicDataSource.DatabaseType.Master, master);
targetDataSources.put(DynamicDataSource.DatabaseType.Read, read);
//將例項化的資料來源放入動態資料來源配置
System.out.println("配置動態資料來源!!!");
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);// 該方法是AbstractRoutingDataSource的方法
//因為事務問題,所以配置的master
dataSource.setDefaultTargetDataSource(master);//設定預設資料來源
System.out.println("----------- DataBaseConfigurationEnd -----------");
return dataSource;
}
}
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>
<groupId>com.pbh</groupId>
<artifactId>springbootdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springbootdemo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!--spring boot 元件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</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-aop</artifactId>
</dependency>
<!--為了方便升級,Spring Boot 釋出了一個新的 spring-boot-properties-migrator 模組。
只要將其作為依賴新增到專案中,它不僅會分析應用程式的環境並在啟動時列印診斷資訊,
而且還會在執行時為專案臨時遷移屬性。在您的應用程式遷移期間,這個模組是必備的。
注意:遷移完成之後,請確保從專案的依賴關係中移除該模組。-->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
</dependency>-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>-->
<!-- spring boot 熱部署外掛 -->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>-->
<!-- mysql connector java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Apache的StringUtils -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<!-- 分頁 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<!-- alibaba的druid資料庫連線池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<!--swagger -->
<dependency>
<groupId>com.battcn</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>2.0.6-RELEASE</version>
</dependency>
<!--mybatis通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
<!--<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<!–建議使用最新版本,最新版本請從專案首頁查詢 –>
<version>4.0.4</version>
</dependency>-->
<!--如果不想每次都寫private final Logger logger = LoggerFactory.getLogger(XXX.class); 可以用註解@Slf4j -->
<!--註解@Slf4j注入後找不到變數log,那就給IDE安裝lombok外掛 安裝完成後重啟IDEA -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!--表明該包只在編譯和測試的時候用 -->
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- spring boot 支援的Maven外掛 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- mybatis generator 自動生成程式碼外掛 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<!-- generatorConfig.xml位置 -->
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
</project>