spring boot自动装配

自动装配是spring boot的一大特点,自动装配其实就是spring把一些常用的bean提前注册到了容器,如redis、jdbc、activemq等,我们可以直接来使用这些bean,所有的自动装配的代码都在spring-boot-autoconfigure这个模块里。

内置了很多,市面上常用的组件基本都包括了。

线程池的自动装配

线程池的自动装配代码在org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration这个类里面。

可以看到类上有一个注解:@ConditionalOnClass({ThreadPoolTaskExecutor.class}),也就是说自动装配是有条件的,前提是在类路径下有这个类, ThreadPoolTaskExecutor这个类是spring的线程池实现类,这个类在spring-context包中,如果引入了这个包,那么spring boot将会向容器注册一个默认的线程池。

默认线程池的参数,我们可以通过配置文件指定,格式如下:

spring.task.execution.pool.core-size=8
spring.task.execution.pool.max-size=Integer.MAX_VALUE
spring.task.execution.pool.queue-capacity=Integer.MAX_VALUE
spring.task.execution.pool.keep-alive=60 //单位是:秒

还有一些其他参数,都在org.springframework.boot.autoconfigure.task.TaskExecutionProperties这个类里面,如果我们不指定的话,会使用默认值。

默认线程池的使用

@Autowired
private ThreadPoolTaskExecutor poolTaskExecutor;

直接使用@Autowired这个注解注入即可。

自定义线程池

自定义线程池的创建,也非常简单,和spring boot的写法并无二致。

@Configuration
public class MyThreadPool {
    @Bean("myThreadPool")
    public ThreadPoolTaskExecutor myThreadPool(ThreadProperties threadProperties) {

        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        threadPool.setCorePoolSize(threadProperties.getSize());//核心线程数量
        threadPool.setMaxPoolSize(threadProperties.getMax());//最大线程数
        threadPool.setQueueCapacity(threadProperties.getQueue());//队列数量
        threadPool.setKeepAliveSeconds(threadProperties.getKeep());//线程所允许的空闲时间
        threadPool.setThreadNamePrefix("myThread-");
        threadPool.setRejectedExecutionHandler((r, executor) -> r.run());
        threadPool.initialize();

        return threadPool;
    }
}

自定义线程池的使用

因为spring boot默认创建了一个,所以加上自定义的,容器中有两个线程池,如果我们使用@Autowired注解注入,看下@Autowired这个注解的逻辑:

首先在容器中查询对应类型的bean

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

如果查询的结果不止一个,那么@Autowired会根据名称来查找。

如果查询的结果为空,那么会抛出异常。

所以使用@Autowired这个注入的话,要保证名称和我们自定义的一致才可以,建议指定名称。

带条件的自定义线程池

@Configuration
public class MyThreadPool {
    @Bean("myThreadPool")
    @Conditional(CacheCondition.class)
    public ThreadPoolTaskExecutor myThreadPool(ThreadProperties threadProperties) {

        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        threadPool.setCorePoolSize(threadProperties.getSize());//核心线程数量
        threadPool.setMaxPoolSize(threadProperties.getMax());//最大线程数
        threadPool.setQueueCapacity(threadProperties.getQueue());//队列数量
        threadPool.setKeepAliveSeconds(threadProperties.getKeep());//线程所允许的空闲时间
        threadPool.setThreadNamePrefix("myThread-");
        threadPool.setRejectedExecutionHandler((r, executor) -> r.run());
        threadPool.initialize();

        return threadPool;
    }
}

这个多了一个条件注解@Conditional(CacheCondition.class),需要满足这个条件,才会创建。如果条件不满足,将不会创建这个线程池,如果自定义的只有这一个的话,使用@Autowired这个注入的话,这个时候将会使用默认的线程池,这个一定要注意,如果不想使用默认的,在使用的时候,最好指定名称。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐