【Spring】 @ConditionalOnExpression 滿足條件才初始化Bean 的奇技淫巧
阿新 • • 發佈:2022-03-27
1.宣告 某個Bean 僅在一定條件下 才初始化Bean,否則 就不初始化。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class ThreadPoolConfiguration {
@Value( "${thread.pool.core.size}")
private Integer coreSize;
@Value("${thread.pool.max.size}")
private Integer maxSize;
@Value("${thread.pool.queue.capacity}")
private Integer queueCapacity;
@Value("${thread.pool.alive.seconds}")
private Integer keepAliveSeconds;
//宣告執行緒池1 僅在appCode=swappingA 或者 B的時候,該Bean即該執行緒池才 初始化
@Bean(name = "myTaskExecutor")
@ConditionalOnExpression("'${app.code}'.equals('swappingA') || '${app.code}'.equals('swappingB')")
public ThreadPoolTaskExecutor myTaskExecutor() {
ThreadPoolTaskExecutor myTaskExecutor = new ThreadPoolTaskExecutor();
myTaskExecutor.setCorePoolSize(coreSize);
myTaskExecutor.setMaxPoolSize(maxSize);
myTaskExecutor.setQueueCapacity(queueCapacity);
myTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
myTaskExecutor.setThreadNamePrefix("my-task-pool-");
return myTaskExecutor;
}
//宣告執行緒池2 僅在appCode=swappingC 或者 B的時候,該Bean即該執行緒池才 初始化
@Bean(name = "myTaskExecutor2")
@ConditionalOnExpression("'${app.code}'.equals('swappingC') || '${app.code}'.equals('swappingB')")
public ThreadPoolTaskExecutor myTaskExecutor2() {
ThreadPoolTaskExecutor myTaskExecutor2 = new ThreadPoolTaskExecutor();
myTaskExecutor2.setCorePoolSize(coreSize);
myTaskExecutor2.setMaxPoolSize(maxSize);
myTaskExecutor2.setQueueCapacity(queueCapacity);
myTaskExecutor2.setKeepAliveSeconds(keepAliveSeconds);
myTaskExecutor2.setThreadNamePrefix("my-task2-pool-");
return myTaskExecutor2;
}
}
2.如上,如果在swappingA應用啟動時,通過@Resource去獲取執行緒池2,就會啟動失敗,找不到該Bean
@Resource
private ThreadPoolTaskExecutor myTaskExecutor2;
或者
@Resource(name = "myTaskExecutor2")
private ThreadPoolTaskExecutor myTaskExecutor2;
啟動就會報錯
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor' available: expected single matching bean but found 1: myTaskExecutor
或者
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'reportTaskExecutor' available
3.所以,想要在swappingA啟動時候,也能取到myTaskExecutor2 該Bean,修改@ConditionalOnExpression的條件
如下標紅新增
@Bean(name = "myTaskExecutor2")
@ConditionalOnExpression(" '${app.code}'.equals('swappingA') || '${app.code}'.equals('swappingC') || '${app.code}'.equals('swappingB')")
public ThreadPoolTaskExecutor myTaskExecutor2() {
ThreadPoolTaskExecutor myTaskExecutor2 = new ThreadPoolTaskExecutor();
myTaskExecutor2.setCorePoolSize(coreSize);
myTaskExecutor2.setMaxPoolSize(maxSize);
myTaskExecutor2.setQueueCapacity(queueCapacity);
myTaskExecutor2.setKeepAliveSeconds(keepAliveSeconds);
myTaskExecutor2.setThreadNamePrefix("my-task2-pool-");
return myTaskExecutor2;
}