Spring ioc 原始碼分析之--beanFactory.registerResolvableDependency()方法
阿新 • • 發佈:2020-08-01
背景: 在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 voidhello() { 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的物件,記得,第二個引數是物件 } }
此時我們在回頭看原始碼,是不是清晰多了呢?