揭密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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定