在Spring中有importBeanDefinitionRegistrar接口,顾名思义,用于对@import注解引入的bean做扩展。该接口如下:
public interface importBeanDefinitionRegistrar {
public void registerBeanDefinitions(
Annotationmetadata importingClassmetadata,
BeanDefinitionRegistry registry);
}
要理解该接口需要先理解@import注解,@import注解主要作用如下:
@Component
@import(Test2.class)
public class Test1 {
}
public class Test2{
}
@SpringBootApplication
public class SpringtestApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringtestApplication.class, args);
System.out.println(context.getBean(Test2.class));
}
}
此时Test2类虽然没有加@Component注解但也被注册为bean了,是因为在Test1中使用了@import注解将其引入。其实@import在Spring中是很有用的,例如各种@Enable...接口便用到了@import注解。
若要对@import注解引入的bean做更细粒度的定义便可以使用importBeanDefinitionRegistrar接口。如下:
@Component
@import(Test2.class)
public class Test1 {
}
public class Test4 {
private String va;
//setter...
}
public class Test2 implements importBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(Test4.class);
definition.getPropertyValues().addPropertyValue("va","hello world");
registry.registerBeanDefinition("tested4",definition);
}
}
@SpringBootApplication
public class SpringtestApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringtestApplication.class, args);
System.out.println(context.getBean(Test4.class));
}
}
此时,在Test1上通过@import引入的Test2,然而Test2实现了importBeanDefinitionRegistrar接口,并且在registerBeanDefinitions方法中注册了Test4,所以Test4没有加@component注解也被注册为bean了。
!!!注意:此时Test2已经不是bean了,被替换为了Test4!!!



