附录 SpringBoot 默认的扫描包是哪个?

Spring Boot 的启动类上标注 @SpringBootApplication 注解 , 其默认扫描包就是启动类所在的包 .

为什么是这样? 我们看看 @SpringBootApplication 注解的定义

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
	......
}

@SpringBootApplication 上的注解 @ComponentScan 根本就没有定义要扫描的包的名称 , Spring 在解析时, 将直接或间接标注@ComponentScan 注解的类所在包作为默认的扫描包 .

一个类使用了@SpringBootApplication来标注 , 就是间接标注了@ComponentScan .

为了验证上面的描述 , 我们看看需要看看源码 , 如何找到对应的源码呢? 这要求大家有一些源码的知识储备 , 需要知道Spring是在哪里解析配置类的 !

其实就是在调用后置处理器的阶段 , 调用后置处理器 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法来解析的 ,我们在该方法中打上断点 , 一路跟踪 (这过程需要对源码又一定的了解 ,第一次追踪会比较耗时) , 调用栈如下:

//为了美观 , 我们将org.springframework 替换为 o.s
parse:126, ComponentScanAnnotationParser (o.s.context.annotation)
doProcessConfigurationClass:287, ConfigurationClassParser (o.s.context.annotation)
processConfigurationClass:245, ConfigurationClassParser (o.s.context.annotation)
parse:198, ConfigurationClassParser (o.s.context.annotation)
parse:167, ConfigurationClassParser (o.s.context.annotation)
processConfigBeanDefinitions:308, ConfigurationClassPostProcessor (o.s.context.annotation)
postProcessBeanDefinitionRegistry:228, ConfigurationClassPostProcessor (o.s.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:272, PostProcessorRegistrationDelegate (o.s.context.support)
invokeBeanFactoryPostProcessors:92, PostProcessorRegistrationDelegate (o.s.context.support)
invokeBeanFactoryPostProcessors:687, AbstractApplicationContext (o.s.context.support)
refresh:525, AbstractApplicationContext (o.s.context.support)
refresh:122, EmbeddedWebApplicationContext (o.s.boot.context.embedded)
refresh:693, SpringApplication (o.s.boot)
refreshContext:360, SpringApplication (o.s.boot)
run:303, SpringApplication (o.s.boot)
run:1118, SpringApplication (o.s.boot)
run:1107, SpringApplication (o.s.boot)
main:14, HelloSpringBootApplication (com.yh.stu.springboot)
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
	Assert.state(this.environment != null, "Environment must not be null");
	Assert.state(this.resourceLoader != null, "ResourceLoader must not be null");
	// 略......
	
	if (basePackages.isEmpty()) {
		// 获取 declaringClass 的包名
		basePackages.add(ClassUtils.getPackageName(declaringClass));
	}

	scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
		@Override
		protected boolean matchClassName(String className) {
			return declaringClass.equals(className);
		}
	});
	// 扫描 basePackages指定的包
	return scanner.doScan(StringUtils.toStringArray(basePackages));
}

这里的 declaringClass 就是我们的启动类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java硕哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值