springboot手动配置,快速入门springboot

  springboot手动配置,快速入门springboot

  @启用自动配置

  @Target(ElementType .TYPE)@ Retention(保留策略.运行时)@ documentated @ Inherited @ auto配置包@ Import(autoconfigurationimportselector。class)public @ interface启用自动配置{ String ENABLED _ OVERRIDE _ PROPERTY= spring。靴子。“启用自动配置”;班级?[]排除()默认{ };string[]排除名称()默认值{ };}标注了@AutoConfigurationPackage,并且导入了自动配置导入选择器

  @Target(ElementType .TYPE)@ Retention(保留策略.运行时)@ Documented @ Inherited @ Import(自动配置包.登记员。class)公共@接口自动配置包{ } @自动配置包注解导入了自动配置包。登记员。

  下面来看看这两个导入类

  自动配置包。注册主任

  这是一个内部类,外部类自动配置包是一个抽象类

  静态类注册器实现ImportBeanDefinitionRegistrar,DeterminableImports { @ Override public void registerbeandedefinitions(annotation metadata元数据,BeanDefinitionRegistry注册表){ //注册注册(注册表,新包导入(元数据)。获取包名());}//这个方法没有地方调用,暂不分析@ Override public set对象确定导入(批注元数据元数据){返回集合。singleton(新包导入(元数据));}}注册

  私有最终字符串包名称包导入(注释元数据元数据){这个。包名=类实用程序。获取包名(元数据。get class name());}包导入也是一个内部类,构造方法中赋值了一个成员变量包名。

  公共静态字符串获取包名(字符串FQ类名){ assert。不为空(FQ类名,’类名不得为null’);int lastDotIndex=FQ类名。lastindexof(PACKAGE _ SEPARATOR);return (lastDotIndex!=-1 ?fqClassName.substring(0,lastDotIndex): );}getPackageName方法中会根据@自动配置包标注类的全限定名,获取@自动配置包标注类的包名。

  然后将@自动配置包标注类的包名赋值给包导入的成员变量包名。

  string get package name(){ return this。包名;}getPackageName方法只是简单的将包导入#包名称返回。

  然后调用外部类自动配置包的静态方法里吉斯

  ter

  

private static final String BEAN = AutoConfigurationPackages.class.getName();public static void register(BeanDefinitionRegistry registry, String... packageNames) { //已经注册过 BEAN 了,代表不是第一次调用AutoConfigurationPackages.Registrar if (registry.containsBeanDefinition(BEAN)) { BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN); ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues(); //将这次调用AutoConfigurationPackages.Registrar,将标注@AutoConfigurationPackage 注解的类的包名添加到 BEAN 的参数中 constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames)); } else { //第一次调用AutoConfigurationPackages.Registrar,注册 BEAN GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(BasePackages.class); //获取BasePackages构造器的参数,是个 String... ,将packageNames放到数组第一个位置 beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(BEAN, beanDefinition); }}

注册AutoConfigurationPackages

 

  

static final class BasePackages { private final List<String> packages; private boolean loggedBasePackageInfo; BasePackages(String... names) { List<String> packages = new ArrayList<>(); for (String name : names) { if (StringUtils.hasText(name)) { packages.add(name); } } this.packages = packages; } List<String> get() { if (!this.loggedBasePackageInfo) { if (this.packages.isEmpty()) { if (logger.isWarnEnabled()) {...//只是输出日志 } } else { if (logger.isDebugEnabled()) { String packageNames = StringUtils.collectionToCommaDelimitedString(this.packages); ...//输出日志 } } this.loggedBasePackageInfo = true; } return this.packages; }}

注册时bean的名称是上面的 BEAN,bean的类为BasePackages。

 

  已经注册过AutoConfigurationPackages

  

private static String[] addBasePackages(ConstructorArgumentValues constructorArguments, String[] packageNames) { //取出BasePackages构造器的参数 String... String[] existing = (String[]) constructorArguments.getIndexedArgumentValue(0, String[].class).getValue(); //创建新的集合,将原有的包名和现有的包名添加进去,用set去重,然后返回 Set<String> merged = new LinkedHashSet<>(); merged.addAll(Arrays.asList(existing)); merged.addAll(Arrays.asList(packageNames)); return StringUtils.toStringArray(merged);}

AutoConfigurationImportSelector

 

  AutoConfigurationImportSelector实现了DeferredImportSelector,DeferredImportSelector实现了ImportSelector。

  

public String[] selectImports(AnnotationMetadata annotationMetadata) { //不起用自动装配 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //获得AutoConfiguration的注解元数据 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } //获取注解的属性 AnnotationAttributes attributes = getAttributes(annotationMetadata); //获取实现EnableAutoConfiguration的类名集合 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //去重 configurations = removeDuplicates(configurations); //获取要排除的类名 Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); //排除 configurations.removeAll(exclusions); //过滤 configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions);}

获取所有EnableAutoConfiguration实现类名

 

  

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { //利用spi获取实现了EnableAutoConfiguration的类名集合 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations;}
protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class;}

去重

 

  

protected final <T> List<T> removeDuplicates(List<T> list) { return new ArrayList<>(new LinkedHashSet<>(list));}

获取要排除的类名

 

  

protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) { Set<String> excluded = new LinkedHashSet<>(); excluded.addAll(asList(attributes, "exclude")); excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName"))); excluded.addAll(getExcludeAutoConfigurationsProperty()); return excluded;}
private List<String> getExcludeAutoConfigurationsProperty() { if (getEnvironment() instanceof ConfigurableEnvironment) { Binder binder = Binder.get(getEnvironment()); return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList) .orElse(Collections.emptyList()); } String[] excludes = getEnvironment().getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class); return (excludes != null) ? Arrays.asList(excludes) : Collections.emptyList();}

过滤

 

  

private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) { long startTime = System.nanoTime(); String[] candidates = StringUtils.toStringArray(configurations); boolean[] skip = new boolean[candidates.length]; boolean skipped = false; for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) { invokeAwareMethods(filter); boolean[] match = filter.match(candidates, autoConfigurationMetadata); for (int i = 0; i < match.length; i++) { if (!match[i]) { skip[i] = true; candidates[i] = null; skipped = true; } } } if (!skipped) { return configurations; } List<String> result = new ArrayList<>(candidates.length); for (int i = 0; i < candidates.length; i++) { if (!skip[i]) { result.add(candidates[i]); } } if (logger.isTraceEnabled()) { int numberFiltered = configurations.size() - result.size(); logger.trace("Filtered " + numberFiltered + " auto configuration class in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms"); } return new ArrayList<>(result);}
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() { return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);}

根据AutoConfigurationImportFilter的实现类过滤自动装配类

 

  到此这篇关于SpringBoot快速通关自动配置应用的文章就介绍到这了,更多相关SpringBoot自动配置内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: