玩转SpringBoot之定时任务@Scheduled线程池配置-
对于定时任务,在SpringBoot中只需要使用@Scheduled 这个注解就能够满足需求,它的出现也给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任务了。
):spring配置文件加入配置定时任务的线程池。因为spring的定时任务默认是单线程,多个任务执行起来时间会有问题。
Scheduled 任务调度注解,主要用于配置定时任务;springboot默认的调度器线程池大小为 1。
创建任务类:使同一个线程中串行执行,如果只有一个定时任务,这样做肯定没问题,当定时任务增多,如果一个任务卡死,会导致其他任务也无法执行。
这里首先定义了Spring自动扫描定时任务所在的package,也就是“cn.zifangsky.task”。
SpringBootApplication / 开启对定时任务的支持 在相应的方法上添加@Scheduled声明需要执行的定时任务。
SpringBoot中开启异步任务
1、搜索关联的线程池定义:上下文中唯一的 TaskExecutor 实例,或一个名为 taskExecutor 的 java.util.concurrent.Executor 实例;2 如果以上都没找到,则会使用 SimpleAsyncTaskExecutor 处理异步方法调用。
2、有一些业务需求,需要是异步进行的,不能影响当前线程的运行,在spring boot中则能通过注解和配置快速实现这个。
3、利用 Spring Initializer 创建一个 gradle 项目 spring-boot-async-task,创建时添加相关依赖。 在 Spring Boot 入口类上配置 @EnableAsync 注解开启异步处理。
正确使用@Async,避免踩坑
当系统未配置任何线程池时 SpringBoot会默认添加一个coreSize=8的 ThreadPoolTaskExecutor 无界线程池,名称applicationTaskExecutor。
答案:可以生效 原因:AsyncAnnotationBeanPostProcessor 优先级是最低 而AnnotationAwareAspectJAutoProxyCreator 优先级是最高,所以Async注解可以不用自己创建代理,而复用AnnotationAwareAspectJAutoProxy创建的代理。
在Spring Boot中,我们只需要使用@Async注解就能简单的将原来的同步函数变为异步函数。开启方法:启动类或者配置类上加@EnableAsync注解,然后在方法或者类上加@Async,类上加注解表示类中方法都实现异步调用。
Async 任务异步执行注解,主要用于方法上,表示当前方法会使用新线程异步执行;springboot默认执行器线程池大小为100。
从控制台可以发现,都是http-nio-8080-exec-1线程触发,说明异步没生效,即@Async失效。后面对controller做了如下改造 访问接口,打印内容如下 这说明在controller其实也是可以用@Async,只是要额外做处理。
SpringBoot异步任务及Async不起作用的原因
同一个类里面调用异步方法不生效:原因默认类内的方法调用不会被aop拦截,即调用方和被调用方是在同一个类中,是无法产生切面的,该对象没有被Spring容器管理。即@Async方法不生效。
任务testA,当前线程:async-thread-pool-1 时间testB:3002 异步方法@Async注解失效情况:(1)在@SpringBootApplication启动类没有添加注解@EnableAsync (2)调用方法和异步方法写在同一个类,需要在不同的类才能有效。
主程序在 异步调用 之后,主程序并不会理会这三个函数是否执行完成了,由于没有其他需要执行的内容,所以程序就 自动结束 了,导致了 不完整 或是 没有输出任务 相关内容的情况。
如果以上都没找到,则会使用 SimpleAsyncTaskExecutor 处理异步方法调用。注意:具有 void 返回类型的带注释方法不能将任何异常发送回调用者,默认情况下此类未捕获异常只会被记录日志。
原因:AsyncAnnotationBeanPostProcessor 优先级是最低 而AnnotationAwareAspectJAutoProxyCreator 优先级是最高,所以Async注解可以不用自己创建代理,而复用AnnotationAwareAspectJAutoProxy创建的代理。
SpringBoot自身没有对异步调用做很大的变动,基本还是使用SpringMVC的@Async 注解 :在使用**@EnableWebMvc**注解的时候也可以开启异步调用,但是在SpringBoot中使用异步调用会使得SpringBoot的AutoConfig一部分功能失效。
SpringBoot是如何配置DispatcherServlet的
1、即所有请求都会被转发到 DispatcherServlet 进行处理。
2、满足上面的条件,就会触发springboot的自动配置。可以看到ServletRegistrationBean是继承自RegistartionBean的,在RegistartionBean的onStart方法中,调用了register方法。
3、DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。
4、这个 WebApplicationInitiator 使用xml或 @配置 班 4这个 WebApplicationInitiator 创建 DispatcherServlet 使用先前创建的上下文。
5、基于java-based方式的spring mvc配置,需要创建一个 配置 类并实现 WebMvcConfigurer 接口;在Spring Boot 5版本都是靠重写 WebMvcConfigurerAdapter 的方法来添加自定义拦截器,消息转换器等。
6、配置文件:Spring Boot的配置文件有多种格式,如properties、yaml、json等,需要根据项目的需要选择相应的格式,并将配置文件放置在正确的位置。
springboot中如何使用线程池及异步线程
因为我们常用的是 ThreadPoolExecutor 线程池,所以去这个类中找。上面配置了线程池,并生成了线程池bean,交给了Spring容器管理,使用时注入即可使用。
注解 :在使用**@EnableWebMvc**注解的时候也可以开启异步调用,但是在SpringBoot中使用异步调用会使得SpringBoot的AutoConfig一部分功能失效。
在SpringBoot中使用异步调用是很简单的,只需要使用@Async注解即可实现方法的异步调用。采用@EnableAsync来开启异步任务支持,另外需要加入@Configuration来把当前类加入springIOC容器中。增加一个service类,用来做积分处理。
Async 任务异步执行注解,主要用于方法上,表示当前方法会使用新线程异步执行;springboot默认执行器线程池大小为100。