问题1:PersonService里面的PersonDao是什么时候赋值的?
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean打一个条件断点
可以看到第一步反射new对象后personDao是没有值的。
可以看到上图,populatebean没执行前personDao还是null
可以看到执行完populateBean后发现personDao有值了,那么依赖注入肯定是在populateBean里面执行的,那么我们直接重新打断点进去看看。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
这里有个遍历beanpostprocessor
AutowiredAnnotationBeanPostProcessor这个类就是处理自动注入的关键类,
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
org.springframework.beans.factory.annotation.InjectionMetadata#inject
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
上图会去寻找所有的候选bean。
如果找不到候选bean,判断注解上的Autowired中required属性是否是必须的,如果是那么报错
直接报错。
如果找到多个bean该如何处理?
org.springframework.beans.factory.support.DefaultListableBeanFactory#determineAutowireCandidate
首先判断是否加了@Primary注解
判断bd是否有@Primary注解,没有的话返回false,如果找不到那么primaryBeanName返回null,找到的话就用该bean.
判断优先级:
这种写法就可以来判断优先级,看注解上的值,比较谁的值小就用那个bean
如果以上两种情况都不是的话:
org.springframework.beans.factory.support.DefaultListableBeanFactory#matchesBeanName
判断候选bean的名字和需要注入的bean名字是否相同,如果相同就使用。
总结:自动注入优先级如下: 1.@Primary 2.@Priority 3.匹配注入的名字