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的对象,记得,第二个参数是对象 } }
此时我们在回头看源码,是不是清晰多了呢?