当前位置: 首页 > news >正文

北京建筑设计公司排行榜搜索引擎排名优化亚当

北京建筑设计公司排行榜,搜索引擎排名优化亚当,阿里云零基础网站建设教学,四川建设人才网官网自动装配流程源码解析#xff08;下#xff09; 引言往期内容主要内容4. 排除指定自动配置组件5. 过滤自动配置组件6. 触发自动配置事件 总结 引言 上篇博文#xff0c;笔者带大家了解了自动装配流程中有关自动配置加载的流程#xff1b; 本篇将介绍自动装配流程剩余的内… 自动装配流程源码解析下 引言往期内容主要内容4. 排除指定自动配置组件5. 过滤自动配置组件6. 触发自动配置事件 总结 引言 上篇博文笔者带大家了解了自动装配流程中有关自动配置加载的流程 本篇将介绍自动装配流程剩余的内容包含了自动配置组件的排除和过滤、触发自动配置事件。 往期内容 在开始本篇的内容介绍之前我们先来看看往期的系列文章【有需要的朋友欢迎关注系列专栏】 Spring Boot 源码学习 Spring Boot 项目介绍 Spring Boot 核心运行原理介绍 【Spring Boot 源码学习】EnableAutoConfiguration 注解 【Spring Boot 源码学习】SpringBootApplication 注解 【Spring Boot 源码学习】走近 AutoConfigurationImportSelector 【Spring Boot 源码学习】自动装配流程源码解析上 主要内容 书接上篇本篇继续从源码分析自动装配流程 4. 排除指定自动配置组件 如果我们在实际使用时并不需要其中的某些组件那就可以通过 EnableAutoConfiguration 注解的 exclude 或 excludeName 属性来进行有针对性的排除 或者 在Spring Boot 的配置文件进行排除。 下面我们来分析一下排除逻辑的源码 SetString exclusions getExclusions(annotationMetadata, attributes);protected SetString getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {SetString excluded new LinkedHashSet();// 获取 exclude 属性 配置的 待排除的自动配置组件excluded.addAll(asList(attributes, exclude));// 获取 excludeName 属性 配置的 待排除的自动配置组件excluded.addAll(asList(attributes, excludeName));// 获取 Spring Boot 配置文件中 配置的 待排除的自动配置组件excluded.addAll(getExcludeAutoConfigurationsProperty());return excluded; }protected ListString getExcludeAutoConfigurationsProperty() {Environment environment getEnvironment();if (environment null) {return Collections.emptyList();}if (environment instanceof ConfigurableEnvironment) {Binder binder Binder.get(environment);return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList).orElse(Collections.emptyList());}String[] excludes environment.getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class);return (excludes ! null) ? Arrays.asList(excludes) : Collections.emptyList(); }上面的代码也挺好理解分别从注解属性 exclude 、 excludeName 以及配置文件中获取待排除的自动配置组件。 下面我们来演示一下该如何配置从而排除我们不需要的自动配置组件 添加注解属性 exclude 和 excludeName 添加配置文件属性 我们启动先前建的 Spring Boot 项目的应用类分别查看到如下的信息 当上面获取了被排除的自动配置组件之后需要对待排除的类进行检查如下所示 checkExcludedClasses(configurations, exclusions);private void checkExcludedClasses(ListString configurations, SetString exclusions) {ListString invalidExcludes new ArrayList(exclusions.size());for (String exclusion : exclusions) {// 如果待排除的自动配置类存在且可以加载// 并且已去重过的自动配置组件中不存在该待排除的自动配置类if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) !configurations.contains(exclusion)) {// 添加到非法的排除列表中invalidExcludes.add(exclusion);}}// 如果存在非法的排除项则抛出相应的异常信息if (!invalidExcludes.isEmpty()) {handleInvalidExcludes(invalidExcludes);} }protected void handleInvalidExcludes(ListString invalidExcludes) {StringBuilder message new StringBuilder();for (String exclude : invalidExcludes) {message.append(\t- ).append(exclude).append(String.format(%n));}throw new IllegalStateException(String.format(The following classes could not be excluded because they are not auto-configuration classes:%n%s,message)); }上述代码中对于待排除类的检查逻辑也好理解如果待排除的自动配置类存在且可以加载【即存在于当前的ClassLoader中】并且已去重过的自动配置组件中不存在该待排除的自动配置类则认为待排除的自动配置类是非法的抛出相关异常。 我们下面通过示例来验证一下 在我们的示例项目中添加一个自动配置类【注意这里只做演示无其他意义】 配置文件添加项目中的一个自动配置类 我们启动先前建的 Spring Boot 项目的应用类可以看到如下的启动异常报错 如果上述检查通过则说明待排除的自动配置类都符合要求则调用如下代码从自动配置集合中移除上面获取的待排除的自动配置类信息。 configurations.removeAll(exclusions);5. 过滤自动配置组件 经过上面的自动配置组件排除逻辑之后接下来就要过滤自动配置组件了而过滤逻辑主要是通过检查配置类的注解是否符合 spring.factories 文件中 AutoConfigurationImportFilter 指定的注解检查条件来决定该过滤哪些自动配置组件。 下面开始分析相关代码如下所示【Spring Boot 2.7.9】 configurations getConfigurationClassFilter().filter(configurations);进入 getConfigurationClassFilter 方法如下所示 private ConfigurationClassFilter getConfigurationClassFilter() {if (this.configurationClassFilter null) {ListAutoConfigurationImportFilter filters getAutoConfigurationImportFilters();for (AutoConfigurationImportFilter filter : filters) {invokeAwareMethods(filter);}this.configurationClassFilter new ConfigurationClassFilter(this.beanClassLoader, filters);}return this.configurationClassFilter; }getConfigurationClassFilter 方法返回一个 ConfigurationClassFilter 实例用来过滤掉不必要的配置类。 继续看 getAutoConfigurationImportFilters 方法如下所示 protected ListAutoConfigurationImportFilter getAutoConfigurationImportFilters() {return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader); }它通过 SpringFactoriesLoader 类的 loadFactories 方法来获取 META-INF/spring.factories 中配置 key 为 AutoConfigurationImportFilter 的 Filters 列表 我们可以查看相关配置了解一下如下所示 # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter\ org.springframework.boot.autoconfigure.condition.OnBeanCondition,\ org.springframework.boot.autoconfigure.condition.OnClassCondition,\ org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition如上所示在 spring-boot-autoconfigure 中默认配置了三个筛选条件OnBeanCondition、OnClassCondition、OnWebApplicationCondition它们均实现了 AutoConfigurationImportFilter 接口。 相关类图如下所示 我们继续往下看 invokeAwareMethods如下所示 private void invokeAwareMethods(Object instance) {if (instance instanceof Aware) {if (instance instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) instance).setBeanClassLoader(this.beanClassLoader);}if (instance instanceof BeanFactoryAware) {((BeanFactoryAware) instance).setBeanFactory(this.beanFactory);}if (instance instanceof EnvironmentAware) {((EnvironmentAware) instance).setEnvironment(this.environment);}if (instance instanceof ResourceLoaderAware) {((ResourceLoaderAware) instance).setResourceLoader(this.resourceLoader);}} }这里先判断传入的 instance 对象是否是 Aware 接口 如果是 Aware 接口则判断是否是它的 BeanClassLoaderAware、 BeanFactoryAware、EnvironmentAware 和 ResourceLoaderAware 这 4 个子接口实现 如果是则调用对应的回调方法设置相应参数。 Aware 接口是一个一个标记超接口它表示一个 bean 有资格通过回调方式从 Spring 容器中接收特定框架对象的通知。具体的方法签名由各个子接口确定但通常应该只包括一个接受单个参数并返回 void 的方法。 继续往下翻看源码在 getConfigurationClassFilter 方法最后我们可以看到它返回了一个内部类 ConfigurationClassFilter 的实例对象。 有了内部类 ConfigurationClassFilter 接下来就可以开始自动配置组件的过滤操作主要是通过内部类 ConfigurationClassFilter 的 filter 方法来实现过滤自动配置组件的功能。 不过在分析 filter 方法之前我们先了解下内部类 ConfigurationClassFilter 中两个成员变量 ListAutoConfigurationImportFilter filters 上面已介绍它是 META-INF/spring.factories 中配置的 key 为 AutoConfigurationImportFilter 的 Filters 列表AutoConfigurationMetadata autoConfigurationMetadata 元数据文件 META-INF/ spring-autoconfigure-metadata.properties 中配置对应实体类详细分析请看下面。 AutoConfigurationMetadata 自动配置元数据这个前面没有涉及到从内部类 ConfigurationClassFilter 的构造函数中我们可以看到如下 this.autoConfigurationMetadata AutoConfigurationMetadataLoader.loadMetadata(classLoader);详细代码由于篇幅受限这里就不贴了大家可以自行查看相关源码从如下的截图中我们也可以直观了解下。 好了现在我们进入 filter 方法中最关键的就是下面 的双层 for 循环处理 ListString filter(ListString configurations) {long startTime System.nanoTime();String[] candidates StringUtils.toStringArray(configurations);boolean skipped false;// 具体的过滤匹配操作for (AutoConfigurationImportFilter filter : this.filters) {boolean[] match filter.match(candidates, this.autoConfigurationMetadata);for (int i 0; i match.length; i) {if (!match[i]) {// 不符合过滤匹配要求则清空当前的自动配置组件candidates[i] null;skipped true;}}}// 如果匹配完了都无需跳过直接返回当前配置即可if (!skipped) {return configurations;}// 有一个不满足过滤匹配要求都重新处理并返回符合要求的自动配置组件ListString result new ArrayList(candidates.length);for (String candidate : candidates) {// 如果当前自动配置组件不满足过滤匹配要求则上面会被清空// 因此这里只需判断即可获取符合要求的自动配置组件if (candidate ! null) {result.add(candidate);}}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 result; }翻看上面的 filter 方法源码我们可以很明显地看到Spring Boot 就是通过如下的代码来实现具体的过滤匹配操作。 boolean[] match filter.match(candidates, this.autoConfigurationMetadata);在介绍如何实现具体的过滤匹配操作之前先来看一下 AutoConfigurationImportFilter 接口的源码 FunctionalInterface public interface AutoConfigurationImportFilter {boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata); }上面的 match 方法就是实现具体的过滤匹配操作 参数 String[] autoConfigurationClasses 待过滤的自动配置类数组AutoConfigurationMetadata autoConfigurationMetadata 自动配置的元数据信息 返回值 过滤匹配后的结果布尔数组数组的大小与 autoConfigurationClasses 一致如果自动配置组件需过滤掉则设置布尔数组对应值为 false。 结合上面的关联类图我们可以看到 AutoConfigurationImportFilter 接口实际上是由抽象类 FilteringSpringBootCondition 来实现的另外该抽象类还定义了一个抽象方法 getOutcomes 然后 OnBeanCondition、OnClassCondition、OnWebApplicationCondition 继承该抽象类实现 getOutcomes 方法完成实际的过滤匹配操作。 抽象类 FilteringSpringBootCondition 的相关源码如下【Spring Boot 2.7.9】 abstract class FilteringSpringBootCondition extends SpringBootConditionimplements AutoConfigurationImportFilter, BeanFactoryAware, BeanClassLoaderAware {// 其他代码省略Overridepublic boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {ConditionEvaluationReport report ConditionEvaluationReport.find(this.beanFactory);// 调用 由子类实现的 getOutcomes 方法完成实际的过滤匹配操作ConditionOutcome[] outcomes getOutcomes(autoConfigurationClasses, autoConfigurationMetadata);boolean[] match new boolean[outcomes.length];// 将 getOutcomes 方法返回结果转换成布尔数组for (int i 0; i outcomes.length; i) {match[i] (outcomes[i] null || outcomes[i].isMatch());if (!match[i] outcomes[i] ! null) {logOutcome(autoConfigurationClasses[i], outcomes[i]);if (report ! null) {report.recordConditionEvaluation(autoConfigurationClasses[i], this, outcomes[i]);}}}return match;}protected abstract ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,AutoConfigurationMetadata autoConfigurationMetadata);// 其他代码省略 }通过上面源码可以看出抽象类 FilteringSpringBootCondition 的 match 方法主要是调用 getOutcomes 方法并将其返回的结果转换成布尔数组。而这个 getOutcomes 方法是过滤匹配的核心功能由抽象类 FilteringSpringBootCondition 的子类来实现它。 有关 OnBeanCondition、OnClassCondition 和 OnWebApplicationCondition 的内容由于篇幅受限后续 Huazie 会再通过一篇博文详细讲解。 6. 触发自动配置事件 经过上面的排除和过滤之后我们需要的自动配置类集合已经可以返回了。不过在返回之前还需要再进行最后一步触发自动配置导入事件用来通知所有注册的自动配置监听器进行相关处理。 fireAutoConfigurationImportEvents(configurations, exclusions);进入 fireAutoConfigurationImportEvents 方法可以看到如下源码 private void fireAutoConfigurationImportEvents(ListString configurations, SetString exclusions) {ListAutoConfigurationImportListener listeners getAutoConfigurationImportListeners();if (!listeners.isEmpty()) {AutoConfigurationImportEvent event new AutoConfigurationImportEvent(this, configurations, exclusions);for (AutoConfigurationImportListener listener : listeners) {invokeAwareMethods(listener);listener.onAutoConfigurationImportEvent(event);}} }接着我们进入 getAutoConfigurationImportListeners 方法里它是通过SpringFactoriesLoader 类提供的 loadFactories 方法将 spring.factories 中配置的接口 AutoConfigurationImportListener 的实现类加载出来。 protected ListAutoConfigurationImportListener getAutoConfigurationImportListeners() {return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader); }spring.factories 中配置的自动配置监听器如下所示 # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener然后将过滤出的自动配置类集合和被排除的自动配置类集合作为入参创建一个 AutoConfigurationImportEvent 事件对象 其中 invokeAwareMethods(listener); 类似上面的 invokeAwareMethods(filter); 这里不再赘述了。 最后调用上述自动配置监听器的 onAutoConfigurationImportEvent 方法并传入上述获取的 AutoConfigurationImportEvent 事件对象来通知所有注册的监听器进行相应的处理。 那这样做有什么好处呢 通过触发 AutoConfigurationImportEvent 事件来通知所有注册的监听器进行相应的处理我们就可以在导入自动配置类之后执行一些附加的自定义逻辑或修改自动配置行为。 总结 本篇 Huazie 带大家通读了 Spring Boot 自动装配逻辑的源码详细分析了自动装配的后续流程主要包含 自动配置的排除 和 过滤。超过万字能够看到这的小伙伴Huazie 在这感谢各位的支持。后续我将持续输出有关 Spring Boot 源码学习系列的博文想要及时了解更新的朋友订阅这里即可。
http://www.dnsts.com.cn/news/55269.html

相关文章:

  • 上海网站建设思创淘宝网站怎么做特价
  • 芜湖高端网站建设阿里巴巴网站建设论文
  • 站外推广怎么做西安网站建设盈科
  • 微网站免费开发平台中小企业网站
  • 新公司网站怎么做推广深圳建筑公司公章
  • 做网站必须要有数据库网站域名管理
  • 贵州省住房和城乡建设网站怎么做最简单的网站
  • 怎样做网站导航界面石家庄网站开发报价
  • wordpress 换数据库陕西seo顾问服务
  • 关于百度网站是多少东莞网站建设和制作
  • 网站百度优化建筑兼职招聘网
  • 重庆做网站_重庆网站建设_重庆网络推广_重庆网络公司做网站前的准备
  • 海南专业网站建设定制有瀑布流的网站
  • 企业网站的搜索引擎推广与优化中企动力为什么留不住人
  • 厦门做网站个人计算机考试网页制作题
  • 山东网站seo开发php网站如何上传数据库
  • 多语言建站系统深圳网站建设公
  • 电脑手机自适应网站的建设清新wordpress主题
  • 南阳专业做网站公司哪家好微网站需要什么
  • 动态电子商务网站 制作网站流量统计怎么做的
  • 深圳做网上商城网站专业营销网络推广哪家好
  • 湖南学校网站建设什么行业 网站
  • 深圳做电子工厂的网站免费的网站推广渠道
  • 东莞微网站建设wordpress+粘贴表格
  • 网站右侧广告代码中英文版网站是怎么做的
  • 网站建设预期周期网上ui设计培训
  • 我国外贸企业网站建设网站升级应注意的问题
  • 单位网站建设典型材料wordpress不支持apk
  • 广州市建设工程安全监督站网站滨州网站建设招聘
  • nike建设网站的目的怎么建立一个个人网站