1. 程式人生 > 實用技巧 >Spring ioc 原始碼分析之--beanFactory.registerResolvableDependency()方法

Spring ioc 原始碼分析之--beanFactory.registerResolvableDependency()方法

背景: 在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的物件,記得,第二個引數是物件
    }
}

此時我們在回頭看原始碼,是不是清晰多了呢?