前言
在实际开发中,有部分的bean需要根据不同的项目环境、配置、甚至类信息来进行条件加载,本文介绍几种常用的根据条件判断是否加载bean的方式
1.Conditional家族注解简介
@ConditionalOnClass:当classpath下存在指定的类时,才会装配或者配置;
@ConditionalOnMissingClass:当classpath下不存在指定的类时,才会装配或者配置;
@ConditionalOnBean:当容器中存在指定的bean时,才会装配或者配置;
@ConditionalOnMissingBean:当容器中不存在指定的bean时,才会装配或者配置;
@ConditionalOnExpression:根据SpEL表达式的值来决定是否装配或者配置;
@ConditionalOnProperty:根据配置文件中指定的属性是否存在来决定是否装配或者配置;
@ConditionalOnResource:当classpath下存在指定的资源文件时,才会装配或者配置;
@ConditionalOnWebApplication:当应用是一个Web应用时,才会装配或者配置;
@ConditionalOnNotWebApplication:当应用不是一个Web应用时,才会装配或者配置;
@ConditionalOnJndi:当JNDI中存在指定的项时,才会装配或者配置;
@ConditionalOnJava:当Java版本满足指定条件时,才会装配或者配置;
@ConditionalOnCloudPlatform:当应用运行在指定的云平台上时,才会装配或者配置;
@ConditionalOnSingleCandidate:当容器中只存在一个候选bean时,才会装配或者配置;
@ConditionalOnClassCondition:自定义条件化装配。
这些注解可以通过多种组合使用,以实现更加复杂的条件化装配逻辑。
Conditional 可作用于方法或者类上
2.ConditionalOnMissingBean和ConditionalOnProperty应用
@Bean(initMethod = "start", destroyMethod = "close")
//代表spring中有该bean,就再执行该方法注入
@ConditionalOnMissingBean
//代表spring.profile.active= private 才注入该bean
@ConditionalOnProperty(prefix = "spring.profile", name="active", havingValue = "private")
public StrangeAdapter strangeAdapter() {
System.out.println("556667777");
StrangeAdapter strangeAdapter = new StrangeAdapter(strangeAppName, strangeAppSecurity, "default", strangeRegisterServer, apolloConfig, null);
return strangeAdapter;
}
3. ConditionalOnBean应用
@Component
@Slf4j
//代表spring中有MqttClientService的bean才加载注入NuwaMqttClient的bean
@ConditionalOnBean(MqttClientService.class)
或者 通过bean name进行判断加载
@ConditionalOnBean(name = {"mqttClientService", "slaveDatasource"})
public class NuwaMqttClient {
@Resource
@Qualifier("mqttClientProxy")
private MqttClientService mqttClient;
@Resource
private MqKafkaProducer mqKafkaProducer;
...
}
4. ConditionalOnMissingBean 应用
@Bean
//代表spring容器中没有masterSlaveDataSource 的bean时进行加载
@ConditionalOnMissingBean(name = "masterSlaveDataSource")
DataSource masterSlaveDataSource(TuYaDynamicDataSource masterDatasource, TuYaDynamicDataSource slaveDatasource) throws SQLException {
MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration("masterSlaveDataSource",
"masterDatasource", Arrays.asList("slaveDatasource"));
Map<String, DataSource> result = new HashMap<>();
result.put("masterDatasource", masterDatasource);
result.put("slaveDatasource", slaveDatasource);
Properties properties = new Properties();
properties.setProperty("sql.show", "false");
// sql执行线程数,为0表示无限制
properties.setProperty("executor.size", "0");
properties.setProperty("max.connections.size.per.query", "10");
return MasterSlaveDataSourceFactory.createDataSource(result, masterSlaveRuleConfig, properties);
}
5.ConditionalOnExpression应用
@Configuration
//上面的配置类使用了@ConditionalOnExpression注解,它的意思是只有当配置文件中的myapp.redis.enabled属性值为true时,才会创建RedisConfig配置类中的bean。
@ConditionalOnExpression("${myapp.redis.enabled:true}")
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate() {
return new RedisTemplate();
}
}
2.非conditional家族根据配置加载
@Service(“lokiRedis”)
//当配置文件中spring.profiles.active = inner 时加载该bean
@Profile(value = {“inner”})
public class LokiRedisImpl implements RedisService {
}