昨晚在使用JUnit測試AOP實現時,出現一個問題。在JUnit使用@AutoWired注入某一個對象,Bean Factory里面有該接口的多個實現,Spring不報錯,而始終注入的是一個實現類的實例。
這種只能分析一下Spring @AutoWired的實現原理來解決了。
1. 在JUnit測試用例實現下setter方法,使用setter進行注入
2. 在setter方法上添加斷點
3. 斷點跟蹤調試
spring事務的底層原理、下面是分析過程:
------------
@AutoWired注解源碼分析:
1. Spring為ITestServicce注入對象
Spring調用AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(Object, String, PropertyValues) line: 600
Spring Native。2. 獲取注入的setter方法
3. 獲取setter方法要注入的參數
4. Spring調用BeanFactory的resolveDependency分析ITestService的依賴
5. BeanFactory調用findAutowiredCandidates為com.itheima.service.TestQ查找ITestService的候選Bean
6. 找到三個候選人[testService2, testService, testServiceProxy]
7. BeanFactory調用determineAutowireCandidate/determinePrimaryCandidate來選擇一個匹配的候選Bean(找@Primary標記的bean)
/**
* Return whether the bean definition for the given bean name has been
* marked as a primary bean.
* @param beanName the name of the bean
* @param beanInstance the corresponding bean instance (can be null)
* @return whether the given bean qualifies as primary
*/
8. BeanFactory調用determineHighestPriorityCandidate來選擇一個優先級最高的候選Bean(Bean要實現Ordered接口)
/**
* Determine the candidate with the highest priority in the given set of beans. As
* defined by the {@link org.springframework.core.Ordered} interface, the lowest
* value has the highest priority.
* @param candidateBeans a Map of candidate names and candidate instances
* that match the required type
* @param requiredType the target dependency type to match against
* @return the name of the candidate with the highest priority,
* or {@code null} if none found
* @see #getPriority(Object)
*/
9. 根據field或者setter參數的名稱進行匹配,如果名字匹配上了,就返回指定的對象,如果沒找到則報錯。
/**
* Determine the name of the wrapped parameter/field.
* @return the declared name (never {@code null})
*/
被@AutoWired修飾的field或者是setter,如果名字和某一個BeanFactory中的name/id一致,則即使有個實現,也會獲取到對應那個名稱的Bean。
根據源碼分析,要解決代理無法注入的方法有三種:
1. 在代理的<bean>上添加primary="true"屬性
2. 使用@Qualifier或者@Resource指定要注入的bean的名字
java pause,?