springboot源码解析-管中窥豹系列之EnableXXX(十)
一、前言
- Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去。
- 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot源码管中窥豹系列。

二、EnableXXX
- 我们上一节讲了自动装配,用到了@SpringBootApplication里面的@EnableAutoConfiguration
- springboot还封装了其它的EnableXXX注解
- 比如我们想开启定时任务,要加上注解:@EnableScheduling
- 比如我们想用异步编程,要加上注解:@EnableAsync
- 自动装配用的是:@Import(AutoConfigurationImportSelector.class)
- 是不是都是这个套路呢?我们研究一下
三、源码分析
我们先看看@EnableScheduling
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}
同样的用到@Import,我们看看SchedulingConfiguration
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
}
- 定义了一个BeanPostProcessor :ScheduledAnnotationBeanPostProcessor
- BeanPostProcessor,我们先简单的说下,相当于一个aop组件,在bean加载的时候调用
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
我们看看ScheduledAnnotationBeanPostProcessor怎么实现的方法?
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof AopInfrastructureBean) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
if (!this.nonAnnotatedClasses.contains(targetClass)) {
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
(MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
method, Scheduled.class, Schedules.class);
return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
});
if (annotatedMethods.isEmpty()) {
this.nonAnnotatedClasses.add(targetClass);
if (logger.isTraceEnabled()) {
logger.trace("No @Scheduled annotations found on bean class: " + targetClass);
}
}
else {
// Non-empty set of methods
annotatedMethods.forEach((method, scheduledMethods) ->
scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName +
"': " + annotatedMethods);
}
}
}
return bean;
}
根据@Scheduled注解,执行相应的定时任务,不细看了
我们在看看@EnableAsync
@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;
}
- 通过@Import加载AsyncConfigurationSelector
- ImportSelector之前说过,通过接口返回的字符串数组,加载bean, 不细看了
好了,我们总结一下:
通过@EnableXXX注解上@Import加载进来相应的类
之后怎么实现就各显神通了,主要是BeanPostProcesser, ImportSelector 和Register

欢迎关注微信公众号:丰极,更多技术学习分享。
springboot源码解析-管中窥豹系列之EnableXXX(十)的更多相关文章
- springboot源码解析-管中窥豹系列之BeanDefine如何加载(十三)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanPostProcessor(十二)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之bean如何生成?(十四)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之web服务器(七)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanDefinition(八)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之自动装配(九)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之BeanFactoryPostProcessor(十一)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- springboot源码解析-管中窥豹系列之总体结构(一)
一.简介 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
随机推荐
- 【uva 11093】Just Finish it up(算法效率--贪心)
题意:环形跑道上有N个加油站,编号为1~N.第 i 个加油站可以加油Ai加仑,从加油站 i 开到下一站需要Bi加仑汽油.问可作为起点走完一圈后回到起点的最小加油站编号. 解法:我们把每个加油站的Ai, ...
- zoj3471 Most Powerful
Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These ato ...
- HDU - 4462 Scaring the Birds
It's harvest season now! Farmer John plants a lot of corn. There are many birds living around his co ...
- Tomcat连接配置
DBCP连接池配置: <bean class="org.apache.tomcat.jdbc.pool.PoolProperties"> <property na ...
- 统计学三大相关性系数:pearson,spearman,kendall
目录 person correlation coefficient(皮尔森相关性系数-r) spearman correlation coefficient(斯皮尔曼相关性系数-p) kendall ...
- js 可选链 & 空值合并 In Action
js 可选链 & 空值合并 In Action const obj = { props: { name: 'eric', }, // prop, 不存在的属性 ️ }; console.log ...
- Web Design Trends for 2017
Web Design Trends for 2017 https://www.awwwards.com/web-design-trends-for-2017.html https://usersnap ...
- HTML script tag type all in one
HTML script tag type all in one script type https://developer.mozilla.org/en-US/docs/Web/HTML/Elemen ...
- Emmet & VSCode
Emmet & VSCode Emmet - the essential toolkit for web-developers https://emmet.io/ https://emmet. ...
- how to disabled alert function in javascript
how to disabled alert function in javascript alert 阻塞主线程 default alert; // ƒ alert() { [native code] ...