切换默认shell到wsl
This commit is contained in:
@@ -1,238 +1,238 @@
|
||||
- [Spring Boot Async](#spring-boot-async)
|
||||
- [Spring Executor和Scheduler的自动配置](#spring-executor和scheduler的自动配置)
|
||||
- [Task Execution and Scheduling](#task-execution-and-scheduling)
|
||||
- [Task Execution Abstraction](#task-execution-abstraction)
|
||||
- [TaskExecutor接口的实现种类](#taskexecutor接口的实现种类)
|
||||
- [TaskExecutor的使用](#taskexecutor的使用)
|
||||
- [Spring TaskScheduler Abstraction](#spring-taskscheduler-abstraction)
|
||||
- [Trigger接口](#trigger接口)
|
||||
- [Trigger实现类](#trigger实现类)
|
||||
- [TaskScheduler实现类](#taskscheduler实现类)
|
||||
- [对任务调度和异步执行的注解支持](#对任务调度和异步执行的注解支持)
|
||||
- [启用Scheduling注解](#启用scheduling注解)
|
||||
- [@Scheduled注解](#scheduled注解)
|
||||
- [@Async注解](#async注解)
|
||||
- [@Async方法的异常处理](#async方法的异常处理)
|
||||
- [Cron表达式](#cron表达式)
|
||||
- [Macros(宏)](#macros宏)
|
||||
|
||||
|
||||
# Spring Boot Async
|
||||
## Spring Executor和Scheduler的自动配置
|
||||
当当前上下文中没有Executor类型的bean对象时,spring boot会自动配置一个ThreadPoolTaskExecutor类型的bean对象,并且将该bean对象和异步task执行(@EnableAsync)和spring mvc异步请求处理关联在一起。
|
||||
该默认创建的ThreadPoolTaskExecutor默认使用8个核心线程,并且线程数量可以根据负载动态的增加或者减少。
|
||||
可以通过如下方式对ThreadPoolTaskExecutor进行配置:
|
||||
```properties
|
||||
# 该线程池最多含有16个线程
|
||||
spring.task.execution.pool.max-size=16
|
||||
# 有有界队列存放task,上限为100
|
||||
spring.task.execution.pool.queue-capacity=100
|
||||
# 当线程空闲10s(默认60s)时会进行回收
|
||||
spring.task.execution.pool.keep-alive=10s
|
||||
# 设置核心线程数量
|
||||
spring.task.execution.pool.core-size=8
|
||||
```
|
||||
如果使用@EnableScheduling,一个ThreadPoolTaskScheduler也可以被配置。该线程池默认使用一个线程,但是也可以动态设置:
|
||||
```properties
|
||||
spring.task.scheduling.thread-name-prefix=scheduling-
|
||||
spring.task.scheduling.pool.size=2
|
||||
```
|
||||
## Task Execution and Scheduling
|
||||
Spring通过TaskExecutor和TaskScheduler接口为task的异步执行和调度提供了抽象。
|
||||
### Task Execution Abstraction
|
||||
Executor对应的是JDK中线程池的概念。在Spring中,TaskExecutor接口和java.util.concurrent.Executor接口相同,该接口中只有一个execute方法(execute(Runnable task)),接受一个task。
|
||||
### TaskExecutor接口的实现种类
|
||||
Spring中包含许多预制的TaskExecutor实现类,该实现类如下:
|
||||
- SyncTaskExecutor:该实现类不会执行异步的调用,所有任务的执行都会发生在调用该executor的线程中。(通常使用在不需要多线程的场景)
|
||||
- SimpleAsyncTaskExecutor:该实现类不会复用任何的线程,相反的,对于每次调用该executor,都会使用一个全新的线程。但是,该实现类的确支持对并发数量的限制,该executor会阻塞任何超过并发数量限制的调用,直到slot被释放为止。(SimpleAsyncTaskExecutor并不支持池化技术)
|
||||
- ConcurrentTaskExecutor:该实现类是java.util.concurrent.Executor实例的adapter,其可以将java.util.concurrent.Executor实例的配置参数以bean properties的形式暴露。(当ThreadPoolTaskExecutor的灵活性无法满足需求时,可以使用ConcurrentTaskExecutor)
|
||||
- ThreadPoolTaskExecutor:该实现类型是最广泛被使用的。该实现类可以通过bean properties来配置java.util.concurrent.ThreadPoolExecutor实例,并且将该实例wrap在TaskExecutor实例中。当想要使用另一种java.util.concurrent.Executor时,可以使用ConcurrentTaskExecutor。
|
||||
- DefaultManagedTaskExecutor:该实现使用了通过JNDI获取的ManagedExecutorService
|
||||
|
||||
### TaskExecutor的使用
|
||||
在springboot中,当使用@EnableAsync时,可以通过配置ThreadPoolExecutor的bean properties来配置线程池的核心线程数和最大线程数等属性。
|
||||
```properties
|
||||
# 该线程池最多含有16个线程
|
||||
spring.task.execution.pool.max-size=16
|
||||
# 有有界队列存放task,上限为100
|
||||
spring.task.execution.pool.queue-capacity=100
|
||||
# 当线程空闲10s(默认60s)时会进行回收
|
||||
spring.task.execution.pool.keep-alive=10s
|
||||
# 设置核心线程数量
|
||||
spring.task.execution.pool.core-size=8
|
||||
```
|
||||
|
||||
## Spring TaskScheduler Abstraction
|
||||
为了在特定的时间点执行task,Spring引入了TaskScheduler接口,接口定义如下:
|
||||
```java
|
||||
public interface TaskScheduler {
|
||||
|
||||
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
||||
|
||||
ScheduledFuture schedule(Runnable task, Instant startTime);
|
||||
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);
|
||||
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Duration period);
|
||||
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);
|
||||
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Duration delay);
|
||||
```
|
||||
> scheduleAtFixedRate和scheduleAtFixedDelay区别:
|
||||
> - fixed rate:表示两个task执行开始时间的间隔
|
||||
> - fixed delay:表示上一个task结束时间和下一个task开始时间的间隔
|
||||
>
|
||||
> 实例如下:
|
||||
> - fixed rate:TTWWWTTTWWT...(开始时间间隔为5)
|
||||
> - fixed delay:TTWWWWWTTTTWWWWWTTTTTTTWWWWWT...(上次结束和下次开始之间的间隔为5)
|
||||
>
|
||||
> **通常,TaskScheduler默认情况下是单线程执行的,故而fixed rate执行时,如果一个Task执行时间超过period时,在当前task执行完成之前,下一个task并不会开始执行。下一个task会等待当前task执行完成之后立马执行。**
|
||||
|
||||
### Trigger接口
|
||||
Trigger接口的核心理念是下次执行事件由上次执行的结果决定。上次执行的结果存储在TriggerContext中。
|
||||
Trigger接口如下:
|
||||
```java
|
||||
public interface Trigger {
|
||||
|
||||
Date nextExecutionTime(TriggerContext triggerContext);
|
||||
}
|
||||
```
|
||||
TriggerContext接口如下:(其具有默认的实现类SimpleTriggerContext)
|
||||
```java
|
||||
public interface TriggerContext {
|
||||
|
||||
Date lastScheduledExecutionTime();
|
||||
|
||||
Date lastActualExecutionTime();
|
||||
|
||||
Date lastCompletionTime();
|
||||
}
|
||||
```
|
||||
### Trigger实现类
|
||||
Spring为Trigger提供了两个实现类,其中CronTrigger允许task的调度按照cron expression来执行(类似linux中的crond)。
|
||||
```java
|
||||
scheduler.schedule(task, new CronTrigger("0 15 9-17 * * MON-FRI"));
|
||||
```
|
||||
Spring的另一个Trigger实现是PeriodicTrigger,其接受一个固定的period期间,一个可选的初始delay值,并接收一个boolean值标识该period是fixed-rate还是fixed-delay。
|
||||
### TaskScheduler实现类
|
||||
如果不需要外部的线程管理,可以使用spring提供的ThreadPoolTaskScheduler,其会将任务委托给ScheduledExecutorService来提供bean-properties形式的配置。
|
||||
|
||||
## 对任务调度和异步执行的注解支持
|
||||
Spring同时对任务调度和异步方法的执行提供注解支持。
|
||||
### 启用Scheduling注解
|
||||
想要启用@Async和@Scheduled注解,必须将@EnableAsync注解和@EnableScheduling注解添加到一个@Configuration类上。
|
||||
```java
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
@EnableScheduling
|
||||
public class AppConfig {
|
||||
}
|
||||
```
|
||||
> **@Async注解的实现是通过proxy模式来实现的,故而如果在类内部调用位于同一个类中的@Async方法,那么代理拦截会失效,此时调用的@Async方法将会同步执行而非异步执行**
|
||||
|
||||
> @Async可以接收一个value值,用于指定目标的执行器(Executor或TaskExecutor的beanName)
|
||||
|
||||
### @Scheduled注解
|
||||
在将@Scheduled注解标注到方法时,可以为其指定一个trigger的元数据,使用示例如下:
|
||||
```java
|
||||
@Scheduled(fixedDelay = 5000)
|
||||
public void doSomething() {
|
||||
// something that should run periodically
|
||||
}
|
||||
```
|
||||
> 默认情况下,fixedDelay、fixedRate、initialDelay的时间单位都是ms,可以指定timeUnit来指定其他的时间单位:
|
||||
> ```java
|
||||
> @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS)
|
||||
> public void doSomething() {
|
||||
> // something that should run periodically
|
||||
> }
|
||||
> ```
|
||||
|
||||
可以为@Scheduled注解使用cron表达式
|
||||
```java
|
||||
@Scheduled(cron="*/5 * * * * MON-FRI")
|
||||
public void doSomething() {
|
||||
// something that should run on weekdays only
|
||||
}
|
||||
```
|
||||
|
||||
### @Async注解
|
||||
通过为方法指定@Async注解,可以让该方法异步执行,该方法的执行通过TaskExecutor。
|
||||
```java
|
||||
@Async
|
||||
void doSomething() {
|
||||
// this will be run asynchronously
|
||||
}
|
||||
```
|
||||
可以为@Async标注的方法指定参数和返回值,但是异步方法的返回值只能为void或是Future类型。
|
||||
在该异步方法的调用方调用返回Future实例的get方法之前,调用方仍然能够执行其他操作,异步方法的执行位于TaskExecutor的线程中。
|
||||
```java
|
||||
@Async
|
||||
Future<String> returnSomething(int i) {
|
||||
// this will be run asynchronously
|
||||
}
|
||||
```
|
||||
不能将@Async注解和生命周期回调(例如@PostConstruct)进行混用,如果想要异步的初始化bean对象,需要按照如下方法:
|
||||
```java
|
||||
public class SampleBeanImpl implements SampleBean {
|
||||
|
||||
@Async
|
||||
void doSomething() {
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SampleBeanInitializer {
|
||||
|
||||
private final SampleBean bean;
|
||||
|
||||
public SampleBeanInitializer(SampleBean bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initialize() {
|
||||
bean.doSomething();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
### @Async方法的异常处理
|
||||
当@Async方法的返回类型是Future类型时,处理async方法执行时抛出的异常非常简单,当在Future对象上调用get方法时异常会被抛出。**但当@Async方法的返回类型是void时,执行时抛出的异常既无法被捕获也无法被传输。可以指定一个AsyncUncaughtExceptionHandler来处理此类异常。**
|
||||
```java
|
||||
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
|
||||
// handle exception
|
||||
}
|
||||
}
|
||||
```
|
||||
### Cron表达式
|
||||
在Spring中,cron表达式格式如下:
|
||||
\* \* \* \* \* \*
|
||||
其代表为(s,min,hour,day of month/\*(1~31)\*/,month/\*(1~12)\*/,day of week/\*(0~7,0 or 7 is sun)\*/)
|
||||
> 规则如下:
|
||||
> - 所有字段都可以用(*)来匹配所有值
|
||||
> - 逗号(,)可以用来分隔同一字段中多个值
|
||||
> - 分号(-)可以用来指定范围,指定的范围左右都包含,eg,1-5代表[1,5]
|
||||
> - 在范围(或是*)后跟随下划线(/)代表间隔,如在分钟字段指定*/20,代表该小时内每过20min
|
||||
> - 对于月份或者day of week,可以使用英文名的前三个字母来代替,大小写不敏感
|
||||
> - 在day of month或day of week字段中可以包含L字母
|
||||
> - 在day of month字段,L代表该月的最后一天,在该字段还可以为L指定一个负的偏移量,如L-n代表该月的倒数第n+1天
|
||||
> - 在day of week字段,L代表该周的最后一天,L前还可以前缀月份的数字或是月份的前三个字母(dL或DDDL,如7L或sunL,代表该月份的最后一个星期日),代该月份的最后一个day of week
|
||||
> - day of month字段可以指定为nW,代表离day of month为n最近的一个工作日,如果n为周六,则该该字段代表的值为周五的day of month,如果n为周六,则该字段代表下周一的day of month(如果n为1其位于周六,其也代表下周一的day of month,1W代表该月的第一个工作日)
|
||||
> - 如果day of month的值为LW,则代表该月的最后一个工作日
|
||||
> - day of week字段还能指定为d#n或DDD#n的形式,代表该月的的第几个d in week(例如SUN#2,代表当前月的第二个星期日)
|
||||
|
||||
#### Macros(宏)
|
||||
Cron表达式可读性不太好,可以使用如下预定义的宏:
|
||||
| Macro | meaning |
|
||||
|:-:|:-:|
|
||||
| @yearly (or @annually) | once a year (0 0 0 1 1 *) |
|
||||
| @monthly | once a month (0 0 0 1 * *) |
|
||||
| @weekly | once a week (0 0 0 * * 0) |
|
||||
| @daily (or @midnight) | once a day (0 0 0 * * *), or |
|
||||
| @hourly | once an hour, (0 0 * * * *) |
|
||||
- [Spring Boot Async](#spring-boot-async)
|
||||
- [Spring Executor和Scheduler的自动配置](#spring-executor和scheduler的自动配置)
|
||||
- [Task Execution and Scheduling](#task-execution-and-scheduling)
|
||||
- [Task Execution Abstraction](#task-execution-abstraction)
|
||||
- [TaskExecutor接口的实现种类](#taskexecutor接口的实现种类)
|
||||
- [TaskExecutor的使用](#taskexecutor的使用)
|
||||
- [Spring TaskScheduler Abstraction](#spring-taskscheduler-abstraction)
|
||||
- [Trigger接口](#trigger接口)
|
||||
- [Trigger实现类](#trigger实现类)
|
||||
- [TaskScheduler实现类](#taskscheduler实现类)
|
||||
- [对任务调度和异步执行的注解支持](#对任务调度和异步执行的注解支持)
|
||||
- [启用Scheduling注解](#启用scheduling注解)
|
||||
- [@Scheduled注解](#scheduled注解)
|
||||
- [@Async注解](#async注解)
|
||||
- [@Async方法的异常处理](#async方法的异常处理)
|
||||
- [Cron表达式](#cron表达式)
|
||||
- [Macros(宏)](#macros宏)
|
||||
|
||||
|
||||
# Spring Boot Async
|
||||
## Spring Executor和Scheduler的自动配置
|
||||
当当前上下文中没有Executor类型的bean对象时,spring boot会自动配置一个ThreadPoolTaskExecutor类型的bean对象,并且将该bean对象和异步task执行(@EnableAsync)和spring mvc异步请求处理关联在一起。
|
||||
该默认创建的ThreadPoolTaskExecutor默认使用8个核心线程,并且线程数量可以根据负载动态的增加或者减少。
|
||||
可以通过如下方式对ThreadPoolTaskExecutor进行配置:
|
||||
```properties
|
||||
# 该线程池最多含有16个线程
|
||||
spring.task.execution.pool.max-size=16
|
||||
# 有有界队列存放task,上限为100
|
||||
spring.task.execution.pool.queue-capacity=100
|
||||
# 当线程空闲10s(默认60s)时会进行回收
|
||||
spring.task.execution.pool.keep-alive=10s
|
||||
# 设置核心线程数量
|
||||
spring.task.execution.pool.core-size=8
|
||||
```
|
||||
如果使用@EnableScheduling,一个ThreadPoolTaskScheduler也可以被配置。该线程池默认使用一个线程,但是也可以动态设置:
|
||||
```properties
|
||||
spring.task.scheduling.thread-name-prefix=scheduling-
|
||||
spring.task.scheduling.pool.size=2
|
||||
```
|
||||
## Task Execution and Scheduling
|
||||
Spring通过TaskExecutor和TaskScheduler接口为task的异步执行和调度提供了抽象。
|
||||
### Task Execution Abstraction
|
||||
Executor对应的是JDK中线程池的概念。在Spring中,TaskExecutor接口和java.util.concurrent.Executor接口相同,该接口中只有一个execute方法(execute(Runnable task)),接受一个task。
|
||||
### TaskExecutor接口的实现种类
|
||||
Spring中包含许多预制的TaskExecutor实现类,该实现类如下:
|
||||
- SyncTaskExecutor:该实现类不会执行异步的调用,所有任务的执行都会发生在调用该executor的线程中。(通常使用在不需要多线程的场景)
|
||||
- SimpleAsyncTaskExecutor:该实现类不会复用任何的线程,相反的,对于每次调用该executor,都会使用一个全新的线程。但是,该实现类的确支持对并发数量的限制,该executor会阻塞任何超过并发数量限制的调用,直到slot被释放为止。(SimpleAsyncTaskExecutor并不支持池化技术)
|
||||
- ConcurrentTaskExecutor:该实现类是java.util.concurrent.Executor实例的adapter,其可以将java.util.concurrent.Executor实例的配置参数以bean properties的形式暴露。(当ThreadPoolTaskExecutor的灵活性无法满足需求时,可以使用ConcurrentTaskExecutor)
|
||||
- ThreadPoolTaskExecutor:该实现类型是最广泛被使用的。该实现类可以通过bean properties来配置java.util.concurrent.ThreadPoolExecutor实例,并且将该实例wrap在TaskExecutor实例中。当想要使用另一种java.util.concurrent.Executor时,可以使用ConcurrentTaskExecutor。
|
||||
- DefaultManagedTaskExecutor:该实现使用了通过JNDI获取的ManagedExecutorService
|
||||
|
||||
### TaskExecutor的使用
|
||||
在springboot中,当使用@EnableAsync时,可以通过配置ThreadPoolExecutor的bean properties来配置线程池的核心线程数和最大线程数等属性。
|
||||
```properties
|
||||
# 该线程池最多含有16个线程
|
||||
spring.task.execution.pool.max-size=16
|
||||
# 有有界队列存放task,上限为100
|
||||
spring.task.execution.pool.queue-capacity=100
|
||||
# 当线程空闲10s(默认60s)时会进行回收
|
||||
spring.task.execution.pool.keep-alive=10s
|
||||
# 设置核心线程数量
|
||||
spring.task.execution.pool.core-size=8
|
||||
```
|
||||
|
||||
## Spring TaskScheduler Abstraction
|
||||
为了在特定的时间点执行task,Spring引入了TaskScheduler接口,接口定义如下:
|
||||
```java
|
||||
public interface TaskScheduler {
|
||||
|
||||
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
||||
|
||||
ScheduledFuture schedule(Runnable task, Instant startTime);
|
||||
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);
|
||||
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Duration period);
|
||||
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);
|
||||
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Duration delay);
|
||||
```
|
||||
> scheduleAtFixedRate和scheduleAtFixedDelay区别:
|
||||
> - fixed rate:表示两个task执行开始时间的间隔
|
||||
> - fixed delay:表示上一个task结束时间和下一个task开始时间的间隔
|
||||
>
|
||||
> 实例如下:
|
||||
> - fixed rate:TTWWWTTTWWT...(开始时间间隔为5)
|
||||
> - fixed delay:TTWWWWWTTTTWWWWWTTTTTTTWWWWWT...(上次结束和下次开始之间的间隔为5)
|
||||
>
|
||||
> **通常,TaskScheduler默认情况下是单线程执行的,故而fixed rate执行时,如果一个Task执行时间超过period时,在当前task执行完成之前,下一个task并不会开始执行。下一个task会等待当前task执行完成之后立马执行。**
|
||||
|
||||
### Trigger接口
|
||||
Trigger接口的核心理念是下次执行事件由上次执行的结果决定。上次执行的结果存储在TriggerContext中。
|
||||
Trigger接口如下:
|
||||
```java
|
||||
public interface Trigger {
|
||||
|
||||
Date nextExecutionTime(TriggerContext triggerContext);
|
||||
}
|
||||
```
|
||||
TriggerContext接口如下:(其具有默认的实现类SimpleTriggerContext)
|
||||
```java
|
||||
public interface TriggerContext {
|
||||
|
||||
Date lastScheduledExecutionTime();
|
||||
|
||||
Date lastActualExecutionTime();
|
||||
|
||||
Date lastCompletionTime();
|
||||
}
|
||||
```
|
||||
### Trigger实现类
|
||||
Spring为Trigger提供了两个实现类,其中CronTrigger允许task的调度按照cron expression来执行(类似linux中的crond)。
|
||||
```java
|
||||
scheduler.schedule(task, new CronTrigger("0 15 9-17 * * MON-FRI"));
|
||||
```
|
||||
Spring的另一个Trigger实现是PeriodicTrigger,其接受一个固定的period期间,一个可选的初始delay值,并接收一个boolean值标识该period是fixed-rate还是fixed-delay。
|
||||
### TaskScheduler实现类
|
||||
如果不需要外部的线程管理,可以使用spring提供的ThreadPoolTaskScheduler,其会将任务委托给ScheduledExecutorService来提供bean-properties形式的配置。
|
||||
|
||||
## 对任务调度和异步执行的注解支持
|
||||
Spring同时对任务调度和异步方法的执行提供注解支持。
|
||||
### 启用Scheduling注解
|
||||
想要启用@Async和@Scheduled注解,必须将@EnableAsync注解和@EnableScheduling注解添加到一个@Configuration类上。
|
||||
```java
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
@EnableScheduling
|
||||
public class AppConfig {
|
||||
}
|
||||
```
|
||||
> **@Async注解的实现是通过proxy模式来实现的,故而如果在类内部调用位于同一个类中的@Async方法,那么代理拦截会失效,此时调用的@Async方法将会同步执行而非异步执行**
|
||||
|
||||
> @Async可以接收一个value值,用于指定目标的执行器(Executor或TaskExecutor的beanName)
|
||||
|
||||
### @Scheduled注解
|
||||
在将@Scheduled注解标注到方法时,可以为其指定一个trigger的元数据,使用示例如下:
|
||||
```java
|
||||
@Scheduled(fixedDelay = 5000)
|
||||
public void doSomething() {
|
||||
// something that should run periodically
|
||||
}
|
||||
```
|
||||
> 默认情况下,fixedDelay、fixedRate、initialDelay的时间单位都是ms,可以指定timeUnit来指定其他的时间单位:
|
||||
> ```java
|
||||
> @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS)
|
||||
> public void doSomething() {
|
||||
> // something that should run periodically
|
||||
> }
|
||||
> ```
|
||||
|
||||
可以为@Scheduled注解使用cron表达式
|
||||
```java
|
||||
@Scheduled(cron="*/5 * * * * MON-FRI")
|
||||
public void doSomething() {
|
||||
// something that should run on weekdays only
|
||||
}
|
||||
```
|
||||
|
||||
### @Async注解
|
||||
通过为方法指定@Async注解,可以让该方法异步执行,该方法的执行通过TaskExecutor。
|
||||
```java
|
||||
@Async
|
||||
void doSomething() {
|
||||
// this will be run asynchronously
|
||||
}
|
||||
```
|
||||
可以为@Async标注的方法指定参数和返回值,但是异步方法的返回值只能为void或是Future类型。
|
||||
在该异步方法的调用方调用返回Future实例的get方法之前,调用方仍然能够执行其他操作,异步方法的执行位于TaskExecutor的线程中。
|
||||
```java
|
||||
@Async
|
||||
Future<String> returnSomething(int i) {
|
||||
// this will be run asynchronously
|
||||
}
|
||||
```
|
||||
不能将@Async注解和生命周期回调(例如@PostConstruct)进行混用,如果想要异步的初始化bean对象,需要按照如下方法:
|
||||
```java
|
||||
public class SampleBeanImpl implements SampleBean {
|
||||
|
||||
@Async
|
||||
void doSomething() {
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SampleBeanInitializer {
|
||||
|
||||
private final SampleBean bean;
|
||||
|
||||
public SampleBeanInitializer(SampleBean bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initialize() {
|
||||
bean.doSomething();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
### @Async方法的异常处理
|
||||
当@Async方法的返回类型是Future类型时,处理async方法执行时抛出的异常非常简单,当在Future对象上调用get方法时异常会被抛出。**但当@Async方法的返回类型是void时,执行时抛出的异常既无法被捕获也无法被传输。可以指定一个AsyncUncaughtExceptionHandler来处理此类异常。**
|
||||
```java
|
||||
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
|
||||
// handle exception
|
||||
}
|
||||
}
|
||||
```
|
||||
### Cron表达式
|
||||
在Spring中,cron表达式格式如下:
|
||||
\* \* \* \* \* \*
|
||||
其代表为(s,min,hour,day of month/\*(1~31)\*/,month/\*(1~12)\*/,day of week/\*(0~7,0 or 7 is sun)\*/)
|
||||
> 规则如下:
|
||||
> - 所有字段都可以用(*)来匹配所有值
|
||||
> - 逗号(,)可以用来分隔同一字段中多个值
|
||||
> - 分号(-)可以用来指定范围,指定的范围左右都包含,eg,1-5代表[1,5]
|
||||
> - 在范围(或是*)后跟随下划线(/)代表间隔,如在分钟字段指定*/20,代表该小时内每过20min
|
||||
> - 对于月份或者day of week,可以使用英文名的前三个字母来代替,大小写不敏感
|
||||
> - 在day of month或day of week字段中可以包含L字母
|
||||
> - 在day of month字段,L代表该月的最后一天,在该字段还可以为L指定一个负的偏移量,如L-n代表该月的倒数第n+1天
|
||||
> - 在day of week字段,L代表该周的最后一天,L前还可以前缀月份的数字或是月份的前三个字母(dL或DDDL,如7L或sunL,代表该月份的最后一个星期日),代该月份的最后一个day of week
|
||||
> - day of month字段可以指定为nW,代表离day of month为n最近的一个工作日,如果n为周六,则该该字段代表的值为周五的day of month,如果n为周六,则该字段代表下周一的day of month(如果n为1其位于周六,其也代表下周一的day of month,1W代表该月的第一个工作日)
|
||||
> - 如果day of month的值为LW,则代表该月的最后一个工作日
|
||||
> - day of week字段还能指定为d#n或DDD#n的形式,代表该月的的第几个d in week(例如SUN#2,代表当前月的第二个星期日)
|
||||
|
||||
#### Macros(宏)
|
||||
Cron表达式可读性不太好,可以使用如下预定义的宏:
|
||||
| Macro | meaning |
|
||||
|:-:|:-:|
|
||||
| @yearly (or @annually) | once a year (0 0 0 1 1 *) |
|
||||
| @monthly | once a month (0 0 0 1 * *) |
|
||||
| @weekly | once a week (0 0 0 * * 0) |
|
||||
| @daily (or @midnight) | once a day (0 0 0 * * *), or |
|
||||
| @hourly | once an hour, (0 0 * * * *) |
|
||||
|
||||
Reference in New Issue
Block a user