@Slf4j@Service// TODO 即使加了懒加载,启动时不报错,但只要调用getBean()时,还是会报错。//@LazypublicclassAsyncServiceImplimplementsAsyncService{@ResourceprivateAsyncServiceasyncService;@Async@OverridepublicvoidasyncExecute(){asyncService.execute();}@Overridepublicvoidexecute(){log.info("异步执行业务代码...");}}
原因
看注解@EnableAsync的声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented// TODO 这里导入了一个ImportSelector@Import(AsyncConfigurationSelector.class)public@interfaceEnableAsync{Class<?extendsAnnotation>annotation()defaultAnnotation.class;booleanproxyTargetClass()defaultfalse;AdviceModemode()defaultAdviceMode.PROXY;intorder()defaultOrdered.LOWEST_PRECEDENCE;}
publicclassAsyncConfigurationSelectorextendsAdviceModeImportSelector<EnableAsync>{privatestaticfinalStringASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME="org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";@Override@NullablepublicString[]selectImports(AdviceModeadviceMode){switch(adviceMode){casePROXY:// TODO spring启动时,会加载这个类。这是一个 @Configuration 注解的类。returnnewString[]{ProxyAsyncConfiguration.class.getName()};caseASPECTJ:returnnewString[]{ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};default:returnnull;}}}
@Configuration@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicclassProxyAsyncConfigurationextendsAbstractAsyncConfiguration{@Bean(name=TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicAsyncAnnotationBeanPostProcessorasyncAdvisor(){Assert.notNull(this.enableAsync,"@EnableAsync annotation metadata was not injected");// TODO 异步注解bean处理器。所有@Async注解的方法,对应bean都会被它处理。AsyncAnnotationBeanPostProcessorbpp=newAsyncAnnotationBeanPostProcessor();bpp.configure(this.executor,this.exceptionHandler);Class<?extendsAnnotation>customAsyncAnnotation=this.enableAsync.getClass("annotation");if(customAsyncAnnotation!=AnnotationUtils.getDefaultValue(EnableAsync.class,"annotation")){bpp.setAsyncAnnotationType(customAsyncAnnotation);}bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));returnbpp;}}
publicabstractclassAbstractAdvisingBeanPostProcessorextendsProxyProcessorSupportimplementsBeanPostProcessor{/**
* TODO 此方法是bean实例创建、依赖注入、初始化方法执行后,才执行的。
*/@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(this.advisor==null||beaninstanceofAopInfrastructureBean){// Ignore AOP infrastructure such as scoped proxies.returnbean;}if(beaninstanceofAdvised){Advisedadvised=(Advised)bean;if(!advised.isFrozen()&&isEligible(AopUtils.getTargetClass(bean))){// Add our local Advisor to the existing proxy's Advisor chain...if(this.beforeExistingAdvisors){advised.addAdvisor(0,this.advisor);}else{advised.addAdvisor(this.advisor);}returnbean;}}if(isEligible(bean,beanName)){ProxyFactoryproxyFactory=prepareProxyFactory(bean,beanName);if(!proxyFactory.isProxyTargetClass()){evaluateProxyInterfaces(bean.getClass(),proxyFactory);}proxyFactory.addAdvisor(this.advisor);customizeProxyFactory(proxyFactory);returnproxyFactory.getProxy(getProxyClassLoader());}// No proxy needed.returnbean;}}