1. @enableAspectJAutoProxy enables automatic proxy support for AspectJ. 2. @enableAsync enable asynchronous method support, 译 文 click: spring4.x Advanced topics (ii): multithreading. 3. @enablescheduling enable scheduled task support, 译 文 click: spring4.x advanced topic (c): Scheduled task Schedule. Later in the SpringMvc series, we will cover the additional use of @enable * by: 1. @enableWebMVC to EnableWeb MVC configuration support. 2. @ EnableConfigurationProperties open support for @ ConfigurationProperties annotation configuration Bean. 3. @EnableJpaRepositories enable support for Spring Data JPA Repository. 4. @ EnableTransactionManagement open annotation type transaction support. 5. @enablecaching Enables annotated caching support.

Enable a feature by simply using @enable * to avoid having to configure a lot of code and make it much easier to use. So how does this amazing feature work? So let’s look at that.

@Configuration
public class SchedulingConfiguration {

    @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }

}Copy the code

Looking at the source code for the @enable * annotations, it turns out that all of them have an @import annotation, which is used to Import configuration classes, which means that these auto-enabled implementations actually Import auto-configured beans. The imported configurations are classified into the following three types:

Type 1: Import configuration classes directly

@Target({java.lang.annotation.ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling
{
}Copy the code

Can see EnableScheduling annotations directly import the Configuration class SchedulingConfiguration, this kind of annotation @ the Configuration, and registered a scheduledAnnotationProcessor Bean, SchedulingConfiguration has the following source code:

@Configuration
public class SchedulingConfiguration {

    @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }

}Copy the code

Type 2: Select configuration classes based on conditions

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {

    Class<? extends Annotation> annotation() default Annotation.class;

    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default Ordered.LOWEST_PRECEDENCE;
}
Copy the code

AsyncConfigurationSelectort conditions to choose you need to import the configuration class. For ImportSelector AsyncConfigurationSelector the root of the interface, this interface needs to be rewritten selectImports method, the prior condition judgment within this method. In this example, if adviceMode is PROXY, the ProxyAsyncConfiguration class is returned. If adviceMode for ASPECTJ, return AspectJAsyncConfiguration configuration class, source code is as follows:

public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> { private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME = "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"; /** * {@inheritDoc} * @return {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration} for * {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()}, respectively */ @Override public String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String[] { ProxyAsyncConfiguration.class.getName() }; case ASPECTJ: return new String[] { ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME }; default: return null; }}}Copy the code

Class 3: Dynamically registered beans

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

    /**
     * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
     * to standard Java interface-based proxies. The default is {@code false}.
     */
    boolean proxyTargetClass() default false;

}Copy the code

AspectJAutoProxyRegistrar ImportBeanDefinitionRegistrar interface is achieved, the ImportBeanDefinitionRegistrar is used at runtime automatically add Bean to an existing configuration class, through rewriting method:

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)Copy the code

The AnnotationMetadata parameter is used to get annotations on the current configuration class, and the BeanDefinitionRegistry parameter is used to register beans. The source code is as follows:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /** * Register, escalate, and configure the AspectJ auto proxy creator based on the value * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing * {@code @Configuration} class. */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); }}}Copy the code

exceptional
Welcome to follow the life designer’s wechat public account



longjiazuoA