Spring ImportAware的使用
2021-01-24 本文已影响0人
念䋛
ImportAware接口的使用
ConfigurationClassPostProcessor的静态内部类ImportAwareBeanPostProcessor的postProcessBeforeInitialization后置处理器在
AbstractAutowireCapableBeanFactory#initializeBean的
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
IOC源码代码中被调用的
这是ImportAware是如何被解析使用的
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) {
ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;
}
这里要注意的是ImportAware是要配合@Import使用
代码中importingClass就是标注了@Import的类
比如
@Import(Bus.class)
Public class Car{}
那么importingClass就为car的元信息
何为 元信息呢
一般都是SimpleAnnotationMetadata类,下面是类的属性,这些就是元数据,其中包括了接口,注解,类名称等
private final String className;
private final int access;
@Nullable
private final String enclosingClassName;
@Nullable
private final String superClassName;
private final boolean independentInnerClass;
private final String[] interfaceNames;
private final String[] memberClassNames;
private final MethodMetadata[] annotatedMethods;
private final MergedAnnotations annotations;
实际项目中比较常见的使用是在自定义注解上添加@Import
举例
@Component
@ImportTest(importTest="helloImportAware")
public class Car implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
}
@Data
@Component
public class ImportAwareTest implements ImportAware {
private String importTest;
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
//这里importMetadata不是ImportTest而是@ImportTest注解标注的类,这里就是Car
//经常通过这种方式获取注解的信息
Map<String, Object> map = importMetadata.getAnnotationAttributes (ImportTest.class.getName ());
AnnotationAttributes attrs = AnnotationAttributes.fromMap(map);
importTest = attrs.getString ("importTest");
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import (ImportAwareTest.class)
public @interface ImportTest {
String importTest() default "";
}
@RestController
public class ControllerTest {
@Autowired
private ImportAwareTest importAwareTest;
@RequestMapping("importAwareTest")
public String importAwareTest(){
return importAwareTest.getImportTest ();
}
}
当从Ioc容器中取出ImportAwareTest的时候,importTest属性就已经被赋值了