有时我们需要在某个配置类中导入其他一些类,并且导入的类也会被添加到 Spring 容器中。此时,可以使用@Import 注解来完成此功能。

如果你看过它的源代码,会发现导入的类支持三种不同的类型。

然而,我认为最好将普通类和带有@Configuration 注解的配置类分开解释。因此,列出了四种不同的类型:

1. 导入普通类
这种导入方式最简单。导入的类将被实例化为一个 bean 对象。

public class A {
}
@Import(A.class)
@Configuration
public class TestConfiguration {
}

通过@Import 注解导入类 A,Spring 可以自动实例化对象 A。然后,可以在需要的地方通过@Autowired 注解进行注入:

@Autowired
private A a;

是不是很神奇?不需要添加@Bean 注解就可以实例化对象。

2. 导入带有@Configuration 注解的配置类
这种导入方式最复杂,因为@Configuration 注解还支持多种组合注解,例如:
@Import @ImportResource @PropertySource 等

public class A {
}
publicclass B {
}
@Import(B.class)
@Configuration
public class AConfiguration {
   @Bean
   public A a() {
   return new A();
   }
}
@Import(AConfiguration.class)
@Configuration
public class TestConfiguration {
}

通过@Import 注解导入一个带有@Configuration 注解的配置类,与该配置类相关的@Import、@ImportResource 和@PropertySource 等注解导入的所有类将一次性全部导入。

3. ImportSelector
这种导入方式需要实现 ImportSelector 接口:

public class AImportSelector implements ImportSelector {
    private static final String CLASS_NAME = "com.demo.cache.service.A";

    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{CLASS_NAME};
    }
}

@Import(AImportSelector.class)
@Configuration
public class TestConfiguration {
}

这种方法的优点是 selectImports 方法返回一个数组,这意味着可以非常方便的导入多个类。

4. ImportBeanDefinitionRegistrar
这种导入方式需要实现 ImportBeanDefinitionRegistrar 接口:

public class AImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(A.class);
        registry.registerBeanDefinition("a", rootBeanDefinition);
    }
}

@Import(AImportBeanDefinitionRegistrar.class)
@Configuration
public class TestConfiguration {
}


最后修改:2025 年 08 月 13 日
个人博客