@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.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
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
pom.xml
<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.0modelVersion>
<groupId>com.pbhgroupId>
<artifactId>springbootdemoartifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>jarpackaging>
<name>springbootdemoname>
<description>Demo project for Spring Bootdescription>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.4.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>3.4version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatypegroupId>
<artifactId>jackson-datatype-jodaartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.modulegroupId>
<artifactId>jackson-module-parameter-namesartifactId>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>1.2.5version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.9version>
dependency>
<dependency>
<groupId>com.battcngroupId>
<artifactId>swagger-spring-boot-starterartifactId>
<version>2.0.6-RELEASEversion>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>2.0.4version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<scope>providedscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-maven-pluginartifactId>
<version>1.3.2version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xmlconfigurationFile>
<overwrite>trueoverwrite>
<verbose>trueverbose>
configuration>
plugin>
plugins>
build>
project>
附上SpringBoot新特性
https://blog.csdn.net/yalishadaa/article/details/79400916
记录springboot从1.5.10升级到2.0.0过程中遇到的问题(上)
https://www.jianshu.com/p/81e2798d6dd1
SpringBoot gitHub 文档
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide