【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(); } }
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; } }