zoukankan      html  css  js  c++  java
  • 【Spring】EnableXXX

    @EnableXXX这一类注解的作用:就是用来启用某一个功能的配置。启用某一功能,仅需要加上一个注解即可生效,可以使组建之间的相互依赖降低了耦合性。

      • @EnableWebSecurity
      • @EnableScheduling
      • @EnableAsync
      • @EnableWebMvc
      • @EnableCaching
      • @EnableAutoConfiguration

      通常代码使用逻辑:以@EnableCaching为例,如果没有配置@EnableCaching,那么@Cacheable注解就不会生效。原因是:@EnableXXX通过相关逻辑,判断某个字段/方法/类上面是否存在相关的注解,如果存在,则让其生效。 


     @EnableScheduling实现逻辑

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Import({SchedulingConfiguration.class})
    @Documented
    public @interface EnableScheduling {
    }

    2.1 关键实现1:SchedulingConfiguration类定义

    @Configuration(
        proxyBeanMethods = false
    )
    @Role(2)
    public class SchedulingConfiguration {
        public SchedulingConfiguration() {
        }
    
        @Bean(
            name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
        )
        @Role(2)
        public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
            return new ScheduledAnnotationBeanPostProcessor();
        }
    }
    View Code

     ScheduledAnnotationBeanPostProcessor.java,实现了多个接口

    public class ScheduledAnnotationBeanPostProcessor implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
        public static final String DEFAULT_TASK_SCHEDULER_BEAN_NAME = "taskScheduler";
        protected final Log logger = LogFactory.getLog(this.getClass());
        private final ScheduledTaskRegistrar registrar;
        @Nullable
        private Object scheduler;
        @Nullable
        private StringValueResolver embeddedValueResolver;
        @Nullable
        private String beanName;
        @Nullable
        private BeanFactory beanFactory;
        @Nullable
        private ApplicationContext applicationContext;
        private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap(64));
        private final Map<Object, Set<ScheduledTask>> scheduledTasks = new IdentityHashMap(16);

      1、实现了继承自:BeanPostProcessor::ProcessAfterInitialization(Object bean, String beanName) 实现,判断方法上面是否存在@Scheduled注解

    public Object postProcessAfterInitialization(Object bean, String beanName) {
            if (!(bean instanceof AopInfrastructureBean) && !(bean instanceof TaskScheduler) && !(bean instanceof ScheduledExecutorService)) {
                Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
                if (!this.nonAnnotatedClasses.contains(targetClass) && AnnotationUtils.isCandidateClass(targetClass, Arrays.asList(Scheduled.class, Schedules.class))) {
                    Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (method) -> {
                        Set<Scheduled> scheduledAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations(method, Scheduled.class, Schedules.class);
                        return !scheduledAnnotations.isEmpty() ? scheduledAnnotations : null;
                    });
                    if (annotatedMethods.isEmpty()) {
                        this.nonAnnotatedClasses.add(targetClass);
                        if (this.logger.isTraceEnabled()) {
                            this.logger.trace("No @Scheduled annotations found on bean class: " + targetClass);
                        }
                    } else {
                        annotatedMethods.forEach((method, scheduledAnnotations) -> {
                            scheduledAnnotations.forEach((scheduled) -> {
                                this.processScheduled(scheduled, method, bean);
                            });
                        });
                        if (this.logger.isTraceEnabled()) {
                            this.logger.trace(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName + "': " + annotatedMethods);
                        }
                    }
                }
    
                return bean;
            } else {
                return bean;
            }
        }
    View Code

      如果存在@Scheduled注解,则在后续处理中,继续解析@Scheduled注解中各种关于定时周期的定义,如fixRate(下图),放入定时任务(最终封装成 java.util.concurrent.ScheduledFuture)执行。

       2、实现了继承自DisposableBean::destroy()方法,最终调用线程池线程(ScheduledFuture::cacel) 和线程池的关闭(ScheduledExecutorService::shutdownNow

    public void destroy() {
            synchronized(this.scheduledTasks) {
                Collection<Set<ScheduledTask>> allTasks = this.scheduledTasks.values();
                Iterator var3 = allTasks.iterator();
    
                label25:
                while(true) {
                    if (var3.hasNext()) {
                        Set<ScheduledTask> tasks = (Set)var3.next();
                        Iterator var5 = tasks.iterator();
    
                        while(true) {
                            if (!var5.hasNext()) {
                                continue label25;
                            }
    
                            ScheduledTask task = (ScheduledTask)var5.next();
                            task.cancel();
                        }
                    }
    
                    this.scheduledTasks.clear();
                    break;
                }
            }
    
            this.registrar.destroy();
        }
    View Code

    2.2 关键实现2:@Import注解定义

      实现的功能:加载它自己对应的配置类,然后启动他的功能。

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
        Class<?>[] value();
    }

      @Import 注解导入的类 有三种,分别是:

        1、ImportSelector: 比如@EnableAsync

    @Import({AsyncConfigurationSelector.class})
    public @interface EnableAsync {

        2、ImportBeanDefinitionRegistrar

        3、普通类:会当作为配置类去处理。

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @Documented
    @Import({DelegatingWebMvcConfiguration.class})
    public @interface EnableWebMvc {
    }
  • 相关阅读:
    HADOOP docker(六):hive简易使用指南
    HADOOP docker(四):安装hive
    HADOOP docker(二):HDFS 高可用原理
    Python 自用代码(调整日期格式)
    Python 自用代码(某方标准类网页源代码清洗)
    python合并多个csv文件并去重
    Python连接MySQL乱码(中文变问号)
    Shell实现循环执行curl向Solr导入json文件
    Python 自用代码(拆分txt文件)
    shell报错:未预期的符号***附近有语法错误
  • 原文地址:https://www.cnblogs.com/clarino/p/15173185.html
Copyright © 2011-2022 走看看