1.作用
- 通常需要与自定义注解和一些Import接口(ImportSelector、ImportBeanDefinitionRegistrar和ImportAware)配合一起使用。在Import接口获取自定义注解中的参数并导入相关bean;
2. 示例:
- EnableCaching注解:使用Import注解导入CachingConfigurationSelector;
//**导入AsyncConfigurationSelector
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
//**代理方式:
AdviceMode mode() default AdviceMode.PROXY;
}
- ImportSelector接口:CachingConfigurationSelector是ImportSelector的实现类,根据EnableCaching注解的mode参数,导入相关的bean;
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
//**获取泛型的类型
Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
//**根据泛型的类型获取注解
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
...
//**获取注解中的AdviceMode参数
AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
//**把AdviceMode传给子类,让子类决定需要导入bean的名称
String[] imports = selectImports(adviceMode);
...
return imports;
}
3.配合使用的相关Import接口
3.1.ImportSelector接口
- ImportSelector接口selectImports方法返回需要导入bean的类名,通常是导入一些配置类;
public interface ImportSelector {
//**根据注解中的参数,返回需要导入到spring容器中的bean的类名
String[] selectImports(AnnotationMetadata importingClassMetadata);
//**返回一个排除函数,用于检测selectImports返回的类名是否需要排除
//**排除函数返回true排除,返回false不排除
@Nullable
default Predicate<String> getExclusionFilter() {
return null;
}
}
3.2.ImportBeanDefinitionRegistrar接口
- ImportBeanDefinitionRegistrar接口registerBeanDefinitions方法使用registry注册相关bean,通常是注册一些配置类;
public interface ImportBeanDefinitionRegistrar {
//**根据注解中的参数,使用registry注册相关bean,importBeanNameGenerator是bean的名称生成器
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
//**根据注解中的参数,使用registry注册相关bean
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}
3.3.ImportAware接口
- Aware接口,注入注解元数据,可获取注解中的参数;
- 需要与@Configuration注解一起使用,ImportAware接口获取注解参数,然后在@Configuration中根据注解参数,使用@Bean注册相关bean,达到与上面两个接口一样的目的;
public interface ImportAware extends Aware {
//**Aware接口,注入注解元数据,可获取注解中的参数
void setImportMetadata(AnnotationMetadata importMetadata);
}
//**根据注解元数据,获取注解中参数的相关代码
AnnotationAttributes enableCaching = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnablCaching.class.getName(), false));
int order = enableCaching.<Integer>getNumber("order");