Spring Bean 批量注册

文章目录

      • @Configration和@Bean注解详解
      • @ComponentScan、@ComponentScans详解
      • @Import
      • 参考

@Configration和@Bean注解详解

  1. @Configuration注解修饰的类,会被spring通过cglib做增强处理,通过cglib会生成一个代理对象,代理会拦截所有被@Bean注解修饰的方法,可以确保一些bean是单例的

  2. 不管@Bean所在的类上是否有@Configuration注解,都可以将@Bean修饰的方法作为一个bean注册到spring容器中

@ComponentScan、@ComponentScans详解

@ComponentScan用于批量注册bean

  1. spring会按照这个注解的配置,递归扫描指定包中的所有类,将满足条件的类批量注册到spring容器中.
  2. 可以通过value、basePackages、basePackageClasses 这几个参数来配置包的扫描范围
  3. 可以通过useDefaultFilters、includeFilters、excludeFilters这几个参数来配置类的过滤器,被过滤器处理之后剩下的类会被注册到容器中
  4. @CompontScan注解会被ConfigurationClassPostProcessor类递归处理,最终得到所有需要注册的类。

@ComponentScan工作的过程:

  1. Spring会扫描指定的包,且会递归下面子包,得到一批类的数组
  2. 然后这些类会经过上面的各种过滤器,最后剩下的类会被注册到容器中

默认情况下,任何参数都不设置的情况下,此时,会将@ComponentScan修饰的类所在的包作为扫描包;默认情况下useDefaultFilters为true,这个为true的时候,spring容器内部会使用默认过滤器,
规则是:凡是类上有@Repository、@Service、@Controller、@Component这几个注解中的任何一个的,那么这个类就会被作为bean注册到spring容器中,所以默认情况下,只需在类上加上这几个注解中的任何一个,这些类就会自动交给spring容器来管理了。

@Import

作用就是和xml配置的 标签作用一样,允许通过它引入@Configuration标注的类 , 引入ImportSelector接口和ImportBeanDefinitionRegistrar接口的实现,也包括 @Component注解的普通类

@Import注解是被下面这个类处理的
org.springframework.context.annotation.ConfigurationClassPostProcessor
@Configuration、@Bean、@CompontentScan、@CompontentScans都是被这个类处理的.

@Import的value常见的有5种用法

  1. value为普通的类
  2. value为@Configuration标注的类
  3. value为@CompontentScan标注的类
  4. value为ImportBeanDefinitionRegistrar接口类型
  5. value为ImportSelector接口类型
  6. value为DeferredImportSelector接口类型

value为ImportBeanDefinitionRegistrar接口类型
这个接口提供了通过spring容器api的方式直接向容器中注册bean。
主要参数

  • importingClassMetadata
    AnnotationMetadata类型的,通过这个可以获取被@Import注解标注的类所有注解的信息。
  • registry
    BeanDefinitionRegistry类型,是一个接口,内部提供了注册bean的各种方法。
    BeanDefinitionRegistry接口:bean定义注册器
    AnnotationConfigApplicationContext类也实现了这个接口
    BeanDefinition接口:bean定义信息
    用来表示bean定义信息的接口,我们向容器中注册bean之前,会通过xml或者其他方式定义bean的各种配置信息,bean的所有配置信息都会被转换为一个BeanDefinition对象,然后通过容器中BeanDefinitionRegistry接口中的方法,将BeanDefinition注册到spring容器中,完成bean的注册操作。

value为ImportBeanDefinitionRegistrar接口类型
用法:

  1. 定义ImportBeanDefinitionRegistrar接口实现类,在registerBeanDefinitions方法中使用registry来注册bean
  2. 使用@Import来导入步骤1中定义的类
  3. 使用步骤2中@Import标注的类作为AnnotationConfigApplicationContext构造参数创建spring容器
  4. 使用AnnotationConfigApplicationContext操作bean

value为ImportSelector接口类型
用法
5. 定义ImportSelector接口实现类,在selectImports返回需要导入的类的名称数组
6. 使用@Import来导入步骤1中定义的类
7. 使用步骤2中@Import标注的类作为AnnotationConfigApplicationContext构造参数创建spring容器
8. 使用AnnotationConfigApplicationContext操作bean

拦截bean实例的创建,返回代理对象,
BeanPostProcessor#postProcessAfterInitialization

DeferredImportSelector接口
springboot中的核心功能@EnableAutoConfiguration就是靠DeferredImportSelector来实现的。
DeferredImportSelector是ImportSelector的子接口,既然是ImportSelector的子接口,所以也可以通过@Import进行导入,这个接口和ImportSelector不同地方有两点:

  1. 延迟导入
  2. 指定导入的类的处理顺序

延迟导入
比如@Import的value包含了多个普通类、多个@Configuration标注的配置类、多个ImportSelector接口的实现类,多个ImportBeanDefinitionRegistrar接口的实现类,还有DeferredImportSelector接口实现类,此时spring处理这些被导入的类的时候,会将DeferredImportSelector类型的放在最后处理,会先处理其他被导入的类,其他类会按照value所在的前后顺序进行处理

参考

@Configration和@Bean注解详解(bean批量注册)
@ComponentScan、@ComponentScans详解(bean批量注册)
@import详解(bean批量注册)

你可能感兴趣的:(Spring,系列)