@Import 注解
文章目录
源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
简介
@Import 注解是 Spring 提供的注解,只能用在类上。
@Import 通过快速导入的方式把类交给 Spring 的 IOC 容器管理。
如何使用
@Import 注解值类型为 Class 数组,支持三种类型的 Class。
- Spring 4.2 之前,支持带有 @Configuration 的配置类;之后也支持普通类。
- ImportSelector 接口的实现类。
- ImportBeanDefinitionRegistrar 的接口实现类。
1)Spring 4.2 之前,支持带有 @Configuration 的配置类;之后也支持普通类
前提是 @Import 修饰的类也是由 Spring 的 IOC 容器管理的,如标记了 @Component 注解等,则将 @Import 中的类交由 Spring IOC 容器管理,并指定优先进行对 @Import 中的类定义的加载。
支持带有 @Configuration 的配置类
支持普通类
可以通过 @Import 来加载 Bean,但需要注意的是这种方式加载的 Bean 的 beanName 为 类的全限定名
。
2)ImportSelector 接口的实现类
public interface ImportSelector {
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);
}
ImportSelector 接口是至 Spring 中导入外部配置的核心接口,在 SpringBoot 的自动化配置和 @EnableXXX (功能性注解)中都有它的存在。
其主要作用是收集需要导入的配置类,在 ConfigurationClassParser 类的 processImports 方法用到。
ImportSelector 接口的 selectImports 方法的返回值会被递归进行解析,解析到的全类名按照 @Configuration 进行处理。 其中全类名可以通过 类名.class.getName() 获取。参数 AnnotationMetadata 表示当前被当前 @Import 注解标注的所有注解的信息。
如果该接口的实现类同时实现 EnvironmentAware, BeanFactoryAware ,BeanClassLoaderAware 或者 ResourceLoaderAware ,那么在调用其selectImports 方法之前先调用上述接口中对应的方法。
示例
需要注意的是,和 使用 @Import 注解导入普通类一样,所创建的 Bean 对应的 beanName 为全类名。
3、ImportBeanDefinitionRegistrar 的接口实现类
类似于第二种 ImportSelector 用法,只不过这种用法对 BeanDefinition 的注册的自定义程度更高。
public interface ImportBeanDefinitionRegistrar {
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}
其中,registerBeanDefinitions 方法的第二个参数 BeanDefinitionRegistry 是负责向 IoC 容器注册解析好的 BeanDefinition。
public interface BeanDefinitionRegistry extends AliasRegistry {
// 注册 BeanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
// 移除 BeanDefinition
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 获取 BeanDefinition
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
}