During Spring Project startup, with each additional BeanPostProcessor, all beans will go through methods postProcessBeforeInitialization & postProcessAfterInitialization.
so by default, these BeanPostProcessor are not registered by default. unless we explictly add annotation like Enable*, then respective BeanPostProcessor will be registered.
@Override public String[] selectImports(AdviceMode adviceMode) { returnswitch (adviceMode) { case PROXY -> new String[] {ProxyAsyncConfiguration.class.getName()}; case ASPECTJ -> new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME}; }; }
@Override publicfinal String[] selectImports(AnnotationMetadata importingClassMetadata) { Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class); Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType); if (attributes == null) { thrownew IllegalArgumentException(String.format( "@%s is not present on importing class '%s' as expected", annType.getSimpleName(), importingClassMetadata.getClassName())); }
privatevoidconfigureProxySupport(ProxyProcessorSupport proxySupport){ if (this.enableResilientMethods != null) { if (this.enableResilientMethods.getBoolean("proxyTargetClass")) { proxySupport.setProxyTargetClass(true); } proxySupport.setOrder(this.enableResilientMethods.getNumber("order")); } }
@Bean(name = "org.springframework.resilience.annotation.internalRetryAnnotationProcessor") @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public RetryAnnotationBeanPostProcessor retryAdvisor(){ RetryAnnotationBeanPostProcessor bpp = new RetryAnnotationBeanPostProcessor(); configureProxySupport(bpp); return bpp; }
@Bean(name = "org.springframework.resilience.annotation.internalConcurrencyLimitProcessor") @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public ConcurrencyLimitBeanPostProcessor concurrencyLimitAdvisor(){ ConcurrencyLimitBeanPostProcessor bpp = new ConcurrencyLimitBeanPostProcessor(); configureProxySupport(bpp); return bpp; }
}
the RetryAnnotationBeanPostProcessor will enhance methods which are annotated with @Retryable. the ConcurrencyLimitBeanPostProcessor will enhance methods which are annotated with @ConcurrencyLimit.
Note: the order really matters, @EnableAsync defined with Order.LOWEST_PRECEDENCE, where @EnableResilientMethods defined with Order.LOWEST_PRECEDENCE - 1.
So, if a method annotated with both @Async and @Retryable, it will be adviced by the RetryAnnotationBeanPostProcessor first.
from the real execution side, the method will be executed in a async thread first, then if failed, retry happened.
based on the mode to select the advice type, either jdk/cglib proxy or AspectJ, any methods annotated with @Transactional with be adviced by the choose in the configuation.
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor(){ returnnew ScheduledAnnotationBeanPostProcessor(); }
}
ScheduledAnnotationBeanPostProcessor will register any methods with @Scheduled annotation to be inboked by a TaskScheduler according to the fixedRate, fixedDelay or cron provided via the annotation.
Title: How Spring Framework Register BeanPostProcessor