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的对象,记得,第二个参数是对象
    }
}

此时我们在回头看源码,是不是清晰多了呢?

 

 

 

 

 

 

 

 

 

 

 

 



posted @ 2020-08-01 11:41  yangxiaohui227  阅读(1092)  评论(0编辑  收藏  举报