Spring6 探析之@Import 注解

发布时间 2023-05-26 20:02:44作者: acdongla

Spring6 探析之@Import 注解

简介

@Import 注解与 @Bean注解的作用相同,都可以将实例注册到IOC中,但区别是,@Import 只能作用在类上,并且使用@Import时,不需要再使用@Configuration注解

下面是 @Import 的源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    
	Class<?>[] value();

}

可以看到,@Import只能作用在类上,并且可以传递字节数组

使用@Import可以有三种注入方式(都是单例的)

  • 直接在字节数组中传递Bean的class字节码文件
  • 实现 ImportSelector 接口注入bean,比较灵活
  • 实现 ImportBeanDefinitionRegistrar 接口注入 bean,最为灵活强大

下面演示这三种注入方式

直接在字节数组中传递Bean的class字节码文件

创建一个User bean

image-20230526194534416

新建一个config类,使用 @Import 传递 User.class 字节码文件

image-20230526194704442

这时候,User bean 就被注入到 IOC中了

实现 ImportSelector 接口注入bean

首先,创建一个 SelectorBean 对象,我们的目的是要将它注入到IOC中

image-20230526194740500

然后,创建一个配置对象,该对象实现 ImportSelector,范围包含 SelectorBean 字节码的数组

image-20230526194827349

最后,仍然是在config类中使用 @Import 注解,不过要注意的是,我们要传递 配置对象 的字节码文件,此时,配置对象 不会被注入到IOC中,而配置对象所管理的bean会被注入到IOC中

image-20230526195016939

实现 ImportBeanDefinitionRegistrar 接口注入 bean

它与第二种方法即为类似,只是函数的使用方法不同

创建 RegistrarBean 对象 ,我们的目的是要将它注入到IOC中

image-20230526195100569

创建配置对象 MyRegistrarBean,用于管理要注入的 bean

可见,函数的使用方式与第二种有所不同

public class MyRegistrarBean implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        String beanName = RegistrarBean.class.getName();
        RootBeanDefinition beanDefinition = new RootBeanDefinition(RegistrarBean.class);
        registry.registerBeanDefinition(beanName, beanDefinition);

    }
}

然后在config类中使用 @Import 注解 ,与第二种相同,将配置类的字节码传递进去,配置类不会被注册进IOC,而配置类所管理的对象可以

image-20230526195355973

测试

查看IOC中所有bean

image-20230526195432581

image-20230526195453490

可以看到,三个对象注册成功了