背景: 在spring ioc refresh()方法中,看到了如下邏輯:


要理解該邏輯的原理,先看場景:有個接口InterFaceA,它有2個實現類A1和A2 那么,如果一個類C 依賴了InterFaceA,此時sprig不知道要注入哪個實現類:
public interface InterFaceA { void hello(); } @Component public class A1 implements InterFaceA { @Override public void hello() { System.out.println("A1"); } } @Component public class A2 implements InterFaceA { @Override public void hello() { System.out.println("hello A2"); } } @Component public class MyComponet { @Autowired private InterFaceA interFaceA; public InterFaceA getInterFaceA() { return interFaceA; } public void setInterFaceA(InterFaceA interFaceA) { this.interFaceA = interFaceA; } }
啟動后會出現異常:

解決方案一:使用@primary注解 該注解的作用是告訴spring,當遇到這種情況時,優先使用哪個實現類,在你要指定的實現類加上該注解即可
@Component @Primary public class A1 implements InterFaceA { @Override public void hello() { System.out.println("A1"); } }
方案二:使用@Qualifier 注解,明確指定使用哪個實現類
@Component public class MyComponet { @Qualifier("a1") @Autowired private InterFaceA interFaceA; public InterFaceA getInterFaceA() { return interFaceA; } public void setInterFaceA(InterFaceA interFaceA) { this.interFaceA = interFaceA; } }
方案三. 前面2種方式是給我們用的,而spring框架遇到這種問題,又該如何處理呢? 例如ApplicationContext 有很多實現類,那要注入哪一個呢? 此時就需要用到beanFactory.registerResolvableDependency(xx接口,接口實現類);
意思是說,當容器中要注入XX接口時,直接使用該方法指定的的實現類即可,那么我們的代碼如何修改,我們要先獲取到beanFactory接口才行,可以通過如下方式:
@Component public class MyFactory implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { beanFactory.registerResolvableDependency(InterFaceA.class,beanFactory.getBean("a1")); //意思是,當遇到需要注入InterFaceA.class的地方,優先使用A1的對象,記得,第二個參數是對象 } }
此時我們在回頭看源碼,是不是清晰多了呢?

