栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

关于注解`@AutoConfigurationPackage`作用

Java 更新时间:发布时间: 百科书网 趣学号
关于注解@AutoConfigurationPackage作用

最近在看SpringBoot源码时发现了这个注解 看了一下 网上的教程和视频几乎都是说该注解作用是扫描我们启动类包和子包下组件并加入容器 然而断点跟踪一下发现 在这个注解导入的组件生效之前 我们启动类包下的内容已经被放入Bean定义信息工厂里了 那这个注解的作用到底是什么那 我们来跟踪一下代码

  • 首先说一下 我们包和子包标注注解的组件 之所以被加载入容器 是因为 @ComponentScan(...}) 注解 它在不填写value的情况下 就会扫描所在包和子包 原理不过多赘述 有兴趣的同学可以看看源码
  • 现在来看看@AutoConfigurationPackage到底干了啥
// 引入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));
		}
}
  • 说白了 就是把我们注解所在包路径加入了容器一个专门记录packageNames的集合里 其他组件也可以加入自己想放入的包路径到这个集合
  • 看到这可能大家更疑惑了?SO?就这?其实这注解真就做了这么多事 我们看看注解的说明

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);
	}
}
  • 这里就比较明确了 在注入JPA核心类时 如果无特殊配置 就会去拿我们的packages做扫描
  • 所以总结一下 该注解的作用是向容器内注入一个组件 组件的作用是保存一些包路径
  • JPA里 利用该路径扫描自己的实体类
  • 如果以后我们要开发一些组件 可以利用该机制 保存一些关心的包路径 并在合适的时机让组件读取 以便实现功能
  • END;
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/273723.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号