“Spring Boot 自动包规则原理”的版本间的差异

来自姬鸿昌的知识库
跳到导航 跳到搜索
第53行: 第53行:
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
 
……
 
……
        static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
+
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
  
 
@Override
 
@Override
 
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
 
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
+
register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
 
}
 
}
  
 
@Override
 
@Override
 
public Set<Object> determineImports(AnnotationMetadata metadata) {
 
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
+
return Collections.singleton(new PackageImports(metadata));
 
}
 
}
  
 
}
 
}
 
……
 
……
</syntaxhighlight>
+
</syntaxhighlight>利用 Registrar 向容器中导入一系列组件,<code>AnnotationMetadata metadata</code> 传入的是 @SpringBootApplication 注解标注类的注解元信息,
 +
 
 +
然后经由 <code>new PackageImport(metadata).getPackageName()</code> 得到 @SpringBootApplication 注解标注类的包名(比如:io.github.jihch),
 +
 
 +
最终目的是将指定一个包下(@SpringBootApplication 注解标注类的包)的所有组件导入进来,
 +
 
 +
这就解释了为什么默认是导入 @SpringBootApplication 注解标注类的包下的所有组件

2023年3月1日 (三) 02:59的版本

https://www.bilibili.com/video/BV19K4y1L7MT/?p=13

引导加载的自动配置类

@SpringBootApplication

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

代表当前是一个配置类,使用 @SpringBootApplication 的类也会是 Spring Boot 中的一个配置类



@ComponentScan

包扫描注解,指定扫描哪些包;



@EnableAutoConfiguration

……
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
……
@AutoConfigurationPackage
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) //给容器中导入一个组件
public @interface AutoConfigurationPackage {

比较关键的是 @Import(AutoConfigurationPackages.Registrar.class) 中导入的 AutoConfigurationPackages.Registrar

AutoConfigurationPackages.java
……	
	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
			register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
		}

		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
			return Collections.singleton(new PackageImports(metadata));
		}

	}
……

利用 Registrar 向容器中导入一系列组件,AnnotationMetadata metadata 传入的是 @SpringBootApplication 注解标注类的注解元信息,

然后经由 new PackageImport(metadata).getPackageName() 得到 @SpringBootApplication 注解标注类的包名(比如:io.github.jihch),

最终目的是将指定一个包下(@SpringBootApplication 注解标注类的包)的所有组件导入进来,

这就解释了为什么默认是导入 @SpringBootApplication 注解标注类的包下的所有组件