@ConditionalOnProperty一般加在@Configurarion、@Component配置的类上或@Bean配置的方法上,表示满足获取到某些配置文件信息后才会配置或加载。
@ConditionalOnProperty源码如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({OnPropertyCondition.class})
public @interface ConditionalOnProperty {
//获取对应property名称的值,与name不可同时使用
String[] value() default {};
//property名称的前缀,可以不配置
String prefix() default "";
//配置信息的完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用
String[] name() default {};
//可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置
String havingValue() default "";
//缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错
boolean matchIfMissing() default false;
}
使用场景:
例如项目框架中配置了单数据源配置方式、多数据源配置方式,可以使用配置文件的一个配置来控制,而不必在某些项目使用单数据源,而某些使用多数据源时改代码了。
多数据源时:
package com.iscas.biz.mp.config.db.multi;
@Slf4j
@ConditionalOnProperty(name = "spring.datasource.multi", havingValue = "true", matchIfMissing = false)
@Configuration
public class DruidConfiguration {
//mysql1
@Value("${spring.datasource.druid.mysql1.filters:stat,wall,logback}")
private String filters;
@Value("${spring.datasource.druid.mysql1.filter.stat.log-slow-sql:true}")
private boolean logslowSql;
@Value("${spring.datasource.druid.mysql1.filter.stat.merge-sql:true}")
private boolean mergeSql;
@Value("${spring.datasource.druid.mysql1.filter.stat.slow-sql-millis:200}")
private long slowSqlMill;
//mysql2
@Value("${spring.datasource.druid.mysql2.filters:stat,wall,logback}")
private String filters2;
@Value("${spring.datasource.druid.mysql2.filter.stat.log-slow-sql:true}")
private boolean logslowSql2;
@Value("${spring.datasource.druid.mysql2.filter.stat.merge-sql:true}")
private boolean mergeSql2;
@Value("${spring.datasource.druid.mysql2.filter.stat.slow-sql-millis:200}")
private long slowSqlMill2;
@Autowired
private DruidMultiDatasource1Properties datasource1Properties;
@Autowired
private DruidMultiDatasource2Properties datasource2Properties;
@Bean(name = "mysql1")
@ConditionalOnProperty(name = "spring.datasource.druid.mysql1.name", havingValue = "mysql1",
matchIfMissing = true)
// @ConfigurationProperties(prefix = "spring.datasource.druid.mysql1")
public DataSource db1(){
DruidDataSource datasource = (DruidDataSource) datasource1Properties.initializeDataSourceBuilder().build();
// datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
log.error("druid configuration initialization filter: "+ e);
}
datasource.setProxyFilters(Arrays.asList(statFilter(),logFilter()));
// datasource.setConnectionProperties(connectionProperties);
return datasource;
}
@Bean(name = "mysql2")
@ConditionalOnProperty(name = "spring.datasource.druid.mysql2.name", havingValue = "mysql2",
matchIfMissing = true)
// @ConfigurationProperties(prefix = "spring.datasource.druid.mysql2")
public DataSource db2(){
DruidDataSource datasource = (DruidDataSource) datasource2Properties.initializeDataSourceBuilder().build();
try {
datasource.setFilters(filters2);
} catch (SQLException e) {
log.error("druid configuration initialization filter: "+ e);
}
datasource.setProxyFilters(Arrays.asList(statFilter(),logFilter()));
// datasource.setConnectionProperties(connectionProperties);
return datasource;
}
/**
* 动态数据源配置
* @return
*/
@Bean
@Primary
public DataSource multipleDataSource (@Qualifier("mysql1") DataSource db1,
@Qualifier("mysql2") DataSource db2) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map< Object, Object > targetDataSources = new HashMap<>(2 << 2);
targetDataSources.put(DbTypeEnum.db1.getValue(), db1 );
targetDataSources.put(DbTypeEnum.db2.getValue(), db2);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(db1);
return dynamicDataSource;
}
@Bean
@Primary
public SqlSessionFactory sqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(multipleDataSource(db1(),db2()));
// sqlSessionFactory.setDataSource(multipleDataSource);
//sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml"));
MybatisConfiguration configuration = new MybatisConfiguration();
//configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
configuration.setMapUnderscoreToCamelCase(true);
configuration.setCacheEnabled(false);
sqlSessionFactory.setConfiguration(configuration);
// sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor()
// paginationInterceptor() //添加分页功能
// });
// sqlSessionFactory.setGlobalConfig(globalConfiguration());
return sqlSessionFactory.getObject();
}
@Bean
@Primary
public StatFilter statFilter(){
StatFilter statFilter = new StatFilter();
statFilter.setSlowSqlMillis(slowSqlMill);
statFilter.setLogSlowSql(logslowSql);
statFilter.setMergeSql(mergeSql);
return statFilter;
}
@Bean
public Slf4jLogFilter logFilter(){
Slf4jLogFilter filter = new Slf4jLogFilter();
// filter.setResultSetLogEnabled(false);
// filter.setConnectionLogEnabled(false);
// filter.setStatementParameterClearLogEnable(false);
// filter.setStatementCreateAfterLogEnabled(false);
// filter.setStatementCloseAfterLogEnabled(false);
// filter.setStatementParameterSetLogEnabled(false);
// filter.setStatementPrepareAfterLogEnabled(false);
return filter;
}
}
单数据源时:
@Slf4j
@ConditionalOnProperty(name = "spring.datasource.single", havingValue = "true", matchIfMissing = false)
@Configuration
public class DruidConfiguration {
@Autowired
private DruidSingleDatasourceProperties druidSingleDatasourceProperties;
@Value("${spring.datasource.druid.filters:stat,wall,logback}")
private String filters;
@Value("${spring.datasource.druid.filter.stat.log-slow-sql:true}")
private boolean logslowSql;
@Value("${spring.datasource.druid.filter.stat.merge-sql:true}")
private boolean mergeSql;
@Value("${spring.datasource.druid.filter.stat.slow-sql-millis:200}")
private long slowSqlMill;
// @Value("${spring.datasource.connectionProperties}")
// private String connectionProperties;
// @Value("${spring.datasource.useGlobalDataSourceStat}")
// private boolean useGlobalDataSourceStat;
@Bean //声明其为Bean实例
@ConditionalOnProperty(name = "spring.datasource.druid.type", havingValue = "com.alibaba.druid.pool.DruidDataSource",
matchIfMissing = true)
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource(){
log.info("------------注册DruidDatasource-----------");
DruidDataSource datasource = (DruidDataSource) druidSingleDatasourceProperties.initializeDataSourceBuilder().build();
// datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
log.info("------------注册Druid过滤器-----------");
try {
datasource.setFilters(filters);
} catch (SQLException e) {
log.error("druid configuration initialization filter: "+ e);
}
datasource.setProxyFilters(Arrays.asList(statFilter(),logFilter()));
log.info("------------注册Druid过滤器结束-----------");
log.info("------------注册DruidDatasource结束-----------");
return datasource;
}
@Bean
@Primary
public StatFilter statFilter(){
StatFilter statFilter = new StatFilter();
statFilter.setSlowSqlMillis(slowSqlMill);
statFilter.setLogSlowSql(logslowSql);
statFilter.setMergeSql(mergeSql);
return statFilter;
}
@Bean
public Slf4jLogFilter logFilter(){
Slf4jLogFilter filter = new Slf4jLogFilter();
// filter.setResultSetLogEnabled(false);
// filter.setConnectionLogEnabled(false);
// filter.setStatementParameterClearLogEnable(false);
// filter.setStatementCreateAfterLogEnabled(false);
// filter.setStatementCloseAfterLogEnabled(false);
// filter.setStatementParameterSetLogEnabled(false);
// filter.setStatementPrepareAfterLogEnabled(false);
return filter;
}
}