springboot-Import注解

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");

版权声明:本文为zhouping118原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。