
最近在看SpringBoot源码时发现了这个注解 看了一下 网上的教程和视频几乎都是说该注解作用是扫描我们启动类包和子包下组件并加入容器 然而断点跟踪一下发现 在这个注解导入的组件生效之前 我们启动类包下的内容已经被放入Bean定义信息工厂里了 那这个注解的作用到底是什么那 我们来跟踪一下代码
// 引入AutoConfigurationPackages.Registrar
@import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage{}...
// 向容器中注入组件
static class Registrar implements importBeanDefinitionRegistrar, Determinableimports {
@Override
public void registerBeanDefinitions(Annotationmetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new Packageimports(metadata).getPackageNames().toArray(new String[0]));
}
}...
// 调用方法 注入组件
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
// private static final String BEAN = AutoConfigurationPackages.class.getName();
// 这最终向容器注入组件 名称是全类名 值是Packageimports 里面包含一个集合 集合中存储packageNames 也就是我们注解所在包
if (registry.containsBeanDefinition(BEAN)) {
basePackagesBeanDefinition beanDefinition = (basePackagesBeanDefinition) registry.getBeanDefinition(BEAN);
beanDefinition.addbasePackages(packageNames);
}
else {
registry.registerBeanDefinition(BEAN, new basePackagesBeanDefinition(packageNames));
}
}
Class for storing auto-configuration packages for reference later (e.g. by JPA entity scanner).
Since:
1.0.0
Author:
Phillip Webb, Dave Syer, Oliver Gierke
看最后一句 e.g. by JPA entity scanner ?JPA实体扫描?那我们看看JPA是怎么玩的
还是一样 挑关键的看看
// 先要引入 HibernateJpaAutoConfiguration
@AutoConfigureAfter({ HibernateJpaAutoConfiguration.class...})
// JAP自动配置的引入
public class JpaRepositoriesAutoConfiguration {}...
// 引入HibernateJpaConfiguration
@import(HibernateJpaConfiguration.class)
public class HibernateJpaAutoConfiguration {}
// 继承JpabaseConfiguration
class HibernateJpaConfiguration extends JpabaseConfiguration {}
// 关键方法 entityManagerFactory中调用getPackagesToScan()
public abstract class JpabaseConfiguration implements BeanFactoryAware {
@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
Map vendorProperties = getVendorProperties();
customizeVendorProperties(vendorProperties);
// getPackagesToScan()!!!
return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan()).properties(vendorProperties)
.mappingResources(getMappingResources()).jta(isJta()).build();
}
// 这里先去拿EntityScanPackages 如果拿不到 就去拿我们的AutoConfigurationPackages
protected String[] getPackagesToScan() {
List packages = EntityScanPackages.get(this.beanFactory).getPackageNames();
if (packages.isEmpty() && AutoConfigurationPackages.has(this.beanFactory)) {
packages = AutoConfigurationPackages.get(this.beanFactory);
}
return StringUtils.toStringArray(packages);
}
}