Spring @Async 原理

@EnableAsync

开启异步功能需要 @EnableAsync 注解,可以以此作为切入点。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 导入了 AsyncConfigurationSelector,很重要
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
   

    // 可以自定义异步的注解来代替 @Async,一般不会使用
	Class<? extends Annotation> annotation() default Annotation.class;

    // 是否使用 CGLIB 代理,这个配置会影响所有使用代理的地方,不止是 @Async
	boolean proxyTargetClass() default false;

    // 代理的 advice 是使用 JDK 还是使用 ASPECTJ,一般不修改
	AdviceMode mode() default AdviceMode.PROXY;

	/**
	 * Indicate the order in which the {@link AsyncAnnotationBeanPostProcessor}
	 * should be applied.
	 * <p>The default is {@link Ordered#LOWEST_PRECEDENCE} in order to run
	 * after all other post-processors, so that it can add an advisor to
	 * existing proxies rather than double-proxy.
	 */
    // 决定 AsyncAnnotationBeanPostProcessor 被应用的顺序,默认是最低优先级,在运行完其他 post-processors 后再被应用
	int order() default Ordered.LOWEST_PRECEDENCE;

}

AsyncConfigurationSelector

public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
   

    private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
          "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";


    @Override
    @NonNull
    public String[] selectImports(AdviceMode adviceMode) {
   
       return switch (adviceMode) {
   
          // 向 Spring 注入一个 ProxyAsyncConfiguration
          case PROXY -> new String[] {
   ProxyAsyncConfiguration.class.getName()};
          case ASPECTJ -> new String[] {
   ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};
       };
    }

}

AsyncConfigurationSelector 继承于 AdviceModeImportSelector,可以通过解析子类的泛型,泛型一般是 EnableXXX 注解类型,比如 AsyncConfigurationSelector 的泛型是 AdviceModeImportSelector<EnableAsync>CachingConfigurationSelector 的泛型是 AdviceModeImportSelector<EnableCaching>,然后根据 AdviceMode 选择要 import 的配置。

public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {
   
	
    // EnableAsync、EnableCaching 注解中都会有一个 mode 属性代表 AdviceMode
    public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";

    protected String getAdviceModeAttributeName() {
   
       return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
    }

    @Override
    public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
   
       // 获取类上的泛型,即 EnableAsync
       Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
       Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
	   // 获取 EnableAsync 的属性
       AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
       if (attributes == null) {
   
          throw new IllegalArgumentException(String.format(
                "@%s is not present on importing class '%s' as expected",
                annType.getSimpleName(), importingClassMetadata.getClassName()));
       }
	   // 获取 EnableAsync 的 mode 属性
       AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
       // 调用 AsyncConfigurationSelector 的 selectImports
       String[] imports = selectImports(adviceMode);
       if (imports == null) {
   
          throw new IllegalArgumentException("Unknown AdviceMode: " + adviceMode);
       }
       return imports;
    }

    @Nullable
    protected abstract String[] selectImports(AdviceMode adviceMode);

}

ProxyAsyncConfiguration

主要就是注册一个 AsyncAnnotationBeanPostProcessor

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
   
    // 注册一个 AsyncAnnotationBeanPostProcessor
	@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
   
		Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
		// AsyncAnnotationBeanPostProcessor
		AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
        // 配置线程池、错误处理器 AsyncUncaughtExceptionHandler
		bpp.configure(this.executor, this.exceptionHandler);
        // this.enableAsync 是 EnableAsync 的属性有,由父类 AbstractAsyncConfiguration 赋值
		Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
        // 设置自定义的异步注解
		if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
   
			bpp.setAsyncAnnotationType(customAsyncAnnotation);
		}
        // 是否使用 CGLIB
		bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
        // Order
		bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
		return bpp;
	}
}

AbstractAsyncConfiguration

@Configuration(proxyBeanMethods = false)
public abstract class AbstractAsyncConfiguration implements ImportAware {
   

    // EnableAsync 的属性
	@Nullable
	protected AnnotationAttributes enableAsync;
	// 线程池
	@Nullable
	protected Supplier<Executor> executor;
	// 异常处理器
	@Nullable
	protected Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;

	@Override
	public void setImportMetadata(AnnotationMetadata importMetadata) {
   
        // EnableAsync 的属性
		this.enableAsync = AnnotationAttributes.fromMap(
				importMetadata.getAnnotationAttributes(EnableAsync.class.getName()));
		if (this.enableAsync == null) {
   
			throw new IllegalArgumentException(
					"@EnableAsync is not present on importing class " + importMetadata.getClassName());
		}
	}

	/**
	 * Collect any {@link AsyncConfigurer} beans through autowiring.
	 */
	@Autowired
	void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
   
        // 获取唯一的线程池、异常处理器的配置
		Supplier<AsyncConfigurer> configurer = SingletonSupplier.of(() -> {
   
			List<AsyncConfigurer> candidates = configurers.stream().toList();
			if (CollectionUtils.isEmpty(candidates)) {
   
				return null;
			}
			if (candidates.size() > 1) {
   
				throw new IllegalStateException("Only one AsyncConfigurer may exist");
			}
			return candidates.get(0);
		});
        // 配置线程池、异常处理器
		this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
		this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
	}

	private <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> provider) {
   
		return () -> {
   
			AsyncConfigurer configurer = supplier.get();
			return (configurer != null ? provider.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值