【Spring】 @ConditionalOnExpression 满足条件才初始化Bean 的奇技淫巧

 

 

 

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;
    }

 

posted @ 2022-03-27 11:44  Angel挤一挤  阅读(1137)  评论(0编辑  收藏  举报