揭密springboot自动装配(1)--ImportSelector

2024-06-04 19:18

本文主要是介绍揭密springboot自动装配(1)--ImportSelector,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

揭密springboot自动装配

  1. 揭密springboot自动装配(1)--ImportSelector
  2. 揭密springboot自动装配(2)--AutoConfigurationImportSelector
  3. 揭密springboot自动装配(3)--ioc及调用selectImposts
  4. 揭密springboot自动装配(4)--ioc及创建beanFactory
  5. 揭密springboot自动装配(5)--ioc及@Autowired注解

在讲这个之前,我们先来个例子热热身


首先我们先来了解下ImportSelector这个接口的应用,ImportSelector接口是spring中导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)都有它的存在,具体怎么用下面走个例子看看

1.实现下ImportSelector

public class UserImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {return new String[]{UserA.class.getName()};}
}

这里我们看到有个selectImports方法,我们需要实现它,返回内容我们可以看到就是个数组,把需要装配进spring容器中的bean的className放进返回数组即可

2.接着我们在启动类中添加@Import(UserImportSelector.class)

@SpringBootApplication
@Import(UserImportSelector.class)
public class DemoApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);Object userA = run.getBeanFactory().getBean(UserA.class);System.out.println(userA.toString());Object userB = run.getBeanFactory().getBean(UserB.class);System.out.println(userB.toString());}}

这里UserB我是没有放在selectImports中的,目的是做下对比

3.跑下我们的程序看看结果

这里你会发现UserA可以被拿到,证明已经交给spring容器中可以拿到,而UserB我没有任何处理,是拿不到的这个毫无疑问到这里肯定有人会问,直接@Import(UserA.class)不就行了,搞那么复杂,嗯,这个没错,甚至我可以跑给你们看下

@SpringBootApplication
@Import({UserImportSelector.class,UserB.class})
public class DemoApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);Object userA = run.getBeanFactory().getBean(UserA.class);System.out.println(userA.toString());Object userB = run.getBeanFactory().getBean(UserB.class);System.out.println(userB.toString());}}

那为什么搞那么复杂?

ImportSelector主要是实现些比较复杂有逻辑性的bean装载,我们可以在selectImports做下逻辑判断,比如@ComponentScan像这个扫描器,我们自己来写一个和它差不多的东西玩玩,起名@UserScan

1.创建注解@UserScan,引用@Import(UserImportSelector.class)

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import(UserImportSelector.class)
public @interface UserScan {@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};
}

2.实现UserImportSelector 

public class UserImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(UserScan.class.getName());if(CollectionUtils.isEmpty(annotationAttributes))return new String[0];String[] basePackages = (String[]) annotationAttributes.get("basePackages");ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);scanner.addIncludeFilter(new AssignableTypeFilter(Object.class));//这里实现包含,相当@ComponentScan  includeFilters//scanner.addExcludeFilter(new AssignableTypeFilter(Object.class));//这里可以实现排除,相当@ComponentScan  excludeFiltersSet<String> classes = new HashSet<>();for (String basePackage : basePackages) {Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);candidateComponents.forEach(e-> {classes.add(e.getBeanClassName());});}return classes.toArray(new String[classes.size()]);//return new String[]{UserA.class.getName()};}
}

3.使用@UserScan("com.example.demo.service"),表示扫描包下的类

@SpringBootApplication
@UserScan("com.example.demo.service")
public class DemoApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);Object userA = run.getBeanFactory().getBean(UserA.class);System.out.println(userA.toString());Object userB = run.getBeanFactory().getBean(UserB.class);System.out.println(userB.toString());}
}

4.我们跑起来看看结果

这样可以看到我们是完全可以在spring容器里面拿到UserA和UserB的

好了,热身例子到这里下文将会从源码上分析springboot自动装载的实现,主要和我们前面讲的ImportSelector接口有关,其中有个叫做AutoConfigurationImportSelector的东西,下文将会提到

这篇关于揭密springboot自动装配(1)--ImportSelector的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1030884

相关文章

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关