springboot扫描组件_Springboot启动扫描包的原理

本文详细探讨了SpringBoot在启动时如何扫描组件的原理。从SpringApplication.run方法开始,逐步分析了createApplicationContext、prepareContext和refreshContext的过程。在createApplicationContext中,创建了BeanDefinitionRegistry并注册了ConfigurationClassPostProcessor。在prepareContext中,根据启动类加载配置。在refreshContext时,调用beanFactoryPostProcessors进行处理。重点在于ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法,它处理了@ComponentScan的解析,从而扫描指定包及其子包下的带有Component注解的类,将它们注册到Spring容器中。
摘要由CSDN通过智能技术生成

参考链接1

参考链接2

所参照代码为Springboot2.1.1

​ 默认情况下,扫描范围是主类xxxApplication所在包及其子目录,可以在后面的具体实现中看到。

​ 从主类中的SpringApplication.run(xxxApplication.class, args);一直点击进入run方法的实现,这里可以看到run方法里有几个关于context的方法分别是:

createApplicationContext()

prepareContext(xxx,xx)

refreshContext(context)

public ConfigurableApplicationContext run(String... args) {

...

try {

...

context = createApplicationContext();

...

prepareContext(context, environment, listeners, applicationArguments,

printedBanner);

refreshContext(context);

....

catch (Throwable ex) {

}

逐个分析:

1.createApplicationContext()

这个方法返回一个类型为AnnotationConfigServletWebServerApplicationContext的context,可以点进去看到这个class为AnnotationConfigServletWebServerApplicationContext类型。

protected ConfigurableApplicationContext createApplicationContext() {

...

case SERVLET:

contextClass = Class.forName(**DEFAULT_SERVLET_WEB_CONTEXT_CLASS**);

break;

case ...

}

}

....

return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);

}

该类的一个父类GenericApplicationContext中,创建了一个beanFactory,这个beanFactory实现了BeanDefinitionRegistry的接口,后面会用到。

public GenericApplicationContext() {

this.beanFactory = new DefaultListableBeanFactory();

}

createApplicationContext返回的语句中调用了AnnotationConfigServletWebServerApplicationContext类的构造函数,

public AnnotationConfigServletWebServerApplicationContext() {

this.reader = new AnnotatedBeanDefinitionReader(this);

this.scanner = new ClassPathBeanDefinitionScanner(this);

}

进入构造函数中的第一个AnnotatedBeanDefinitionReader,一直点到registerAnnotationConfigProcessors的方法:

public static Set registerAnnotationConfigProcessors(

BeanDefinitionRegistry registry, @Nullable Object source) {

//创建了一个beanFactory

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

if (beanFactory != null) {

.....

}

Set beanDefs = new LinkedHashSet<>(8);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {

RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);

def.setSource(source);

//添加了一个类型为CON

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值