首先建一个demo
public static void main(String[] args) {
GenericApplicationContext context=new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(
context.getDefaultListableBeanFactory());
context.registerBean("bean",Bean.class);
context.registerBean("bean1", Bean1.class);
context.registerBean("bean2", Bean2.class);
context.registerBean("bean3", Bean3.class);
context.refresh();
}
static class Bean{
MyInterface myBean;
}
interface MyInterface{}
static class Bean1 implements MyInterface{};
static class Bean2 implements MyInterface{};
static class Bean3 implements MyInterface{};
MyInterface是自定义的接口,接口有多个实现类,分别是Bean1、Bean2、Bean3。
一、最低优先级
也就是平时比较常用的 @Qualifier 注解,与 @Autowired 配合使用:
static class Bean{
MyInterface myBean;
@Autowired
@Qualifier("bean3")
public void setBean2(MyInterface bean){
System.out.println(bean);
this.myBean=bean;
}
}
通过 @Qualifier("") 指定要注入的bean,实现选择性注入
结果:
二、第二优先级
context.registerBean("bean",Bean.class,b->{
// 第二优先级
((RootBeanDefinition) b).setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
});
其中 AUTOWIRE_BY_NAME 也就意味着按 bean 的名称的 set 方法进行选择注入,这里使用bean2作为要注入的bean,所以方法名为 setBean2() ,即使加了 @Qualifier 注解,由于优先级的原因,将优先按名称注入。
static class Bean{
MyInterface myBean;
@Autowired
@Qualifier("bean3")
public void setBean2(MyInterface bean){
System.out.println(bean);
this.myBean=bean;
}
}
结果:
三、最高优先级
context.registerBean("bean",Bean.class,b->{
// 最高优先级
b.getPropertyValues().add("bean2",new RuntimeBeanReference("bean1"));
});
这段代码相当于在原始Spring框架的xml配置文件中的配置:
<property name="bean2" ref="bean1"/>
bean的引用指向了bean1,所以实际按bean1注入
即使加了上述的 @Qualifier注解和set方法,仍然按配置的引用bean1执行,结果:
最后给出整体的代码:
public class TestInjection {
public static void main(String[] args) {
GenericApplicationContext context=new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(
context.getDefaultListableBeanFactory());
context.registerBean("bean",Bean.class,b->{
// 最高优先级(相当于<property name="bean2" ref="bean1" />)
b.getPropertyValues().add("bean2",new RuntimeBeanReference("bean1"));
// 第二优先级
((RootBeanDefinition) b).setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
});
context.registerBean("bean1", Bean1.class);
context.registerBean("bean2", Bean2.class);
context.registerBean("bean3", Bean3.class);
context.refresh();
}
static class Bean{
MyInterface myBean;
@Autowired @Qualifier("bean3")
public void setBean2(MyInterface bean){
System.out.println(bean);
this.myBean=bean;
}
}
interface MyInterface{}
static class Bean1 implements MyInterface{};
static class Bean2 implements MyInterface{};
static class Bean3 implements MyInterface{};
}