3.springboot-@Autowired和@Value工作原理
1.簡介
A.名詞說明
- spring bean生命週期
- 複合建構函式(synthetic):由編譯器引入的建構函式,主要用於JVM內部使用;
- 橋接方法(bridge):由編譯器引入的方法,主要用於JVM內部使用;
B.@Autowired與@Value功能
- @Autowired與@Value功能基本相同,都可以自動裝配bean;
- @Value除了可以自動裝配bean外,還可以自動裝配配置引數。裝配配置引數時,也可以配置引數寫在方法上;
@Component
public class MyAutowiredDemo {
@Value("user")
public Object configInt;
@Value("${spring.test.config-int}")
public void test(Object configInt) {
System.out.println(configInt);
}
}
2.InjectionMetadata注入後設資料
InjectionMetadata(類的注入後設資料),描述每個依賴spring注入的java類,以及所有需要注入member(Member是java欄位、方法和建構函式的父類)的相關資訊;
//**類的注入後設資料(描述每個依賴spring注入的java類,以及所有需要注入member的相關資訊)
public class InjectionMetadata {
//**空後設資料
public static final InjectionMetadata EMPTY = new InjectionMetadata(Object.class, Collections.emptyList()) {
@Override
protected boolean needsRefresh(Class<?> clazz) {
return false;
}
@Override
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
}
@Override
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) {
}
@Override
public void clear(@Nullable PropertyValues pvs) {
}
};
//**注入的目標類
private final Class<?> targetClass;
//**目標類所有注入元素的集合
private final Collection<InjectedElement> injectedElements;
//**檢查的注入元素集合
@Nullable
private volatile Set<InjectedElement> checkedElements;
//**構造方法
public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
//**檢查是否需要重新整理
protected boolean needsRefresh(Class<?> clazz) {
return this.targetClass != clazz;
}
//**遍歷注入元素集合檢查member是否註冊到externallyManagedConfigMembers(spring管理的配置成員集合)
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
//**如注入元素對應的member沒有註冊到externallyManagedConfigMembers,則註冊
//**然後把注入元素新增到checkedElements
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
//**遍歷注入元素集合,呼叫注入元素的inject方法注入member依賴的bean
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
//**遍歷注入元素集合,呼叫注入元素的clearPropertySkipping方法清除所有已經注入的member
public void clear(@Nullable PropertyValues pvs) {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.clearPropertySkipping(pvs);
}
}
}
//**靜態方法,建立InjectionMetadata物件
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
}
//**靜態方法,檢查是否需要重新整理
public static boolean needsRefresh(@Nullable InjectionMetadata metadata, Class<?> clazz) {
return (metadata == null || metadata.needsRefresh(clazz));
}
//**注入元素(描述每個依賴spring注入的member相關資訊)
public abstract static class InjectedElement {
//**member
protected final Member member;
//**member是否是欄位
protected final boolean isField;
//**member的屬性描述器
@Nullable
protected final PropertyDescriptor pd;
//**是否跳過
@Nullable
protected volatile Boolean skip;
//**構造方法
protected InjectedElement(Member member, @Nullable PropertyDescriptor pd) {
this.member = member;
this.isField = (member instanceof Field);
this.pd = pd;
}
//**獲取member依賴spring注入的bean型別
protected final Class<?> getResourceType() {
//**如果是欄位,則直接返回欄位的型別
if (this.isField) {
return ((Field) this.member).getType();
}
//**如果包含屬性描述器,則使用屬性描述器獲取型別
else if (this.pd != null) {
return this.pd.getPropertyType();
}
else { //**如果是方法,則返回第一個引數的型別
return ((Method) this.member).getParameterTypes()[0];
}
}
//**檢查指定類是否可以注入到member(指定類和member依賴bean是否存在繼承關係)
protected final void checkResourceType(Class<?> resourceType) {
if (this.isField) {
Class<?> fieldType = ((Field) this.member).getType();
if (!(resourceType.isAssignableFrom(fieldType) || fieldType.isAssignableFrom(resourceType))) {
throw new IllegalStateException("Specified field type [" + fieldType +
"] is incompatible with resource type [" + resourceType.getName() + "]");
}
}
else {
Class<?> paramType =
(this.pd != null ? this.pd.getPropertyType() : ((Method) this.member).getParameterTypes()[0]);
if (!(resourceType.isAssignableFrom(paramType) || paramType.isAssignableFrom(resourceType))) {
throw new IllegalStateException("Specified parameter type [" + paramType +
"] is incompatible with resource type [" + resourceType.getName() + "]");
}
}
}
//**注入member依賴的bean(實際沒有使用,使用的其子類AutowiredFieldElement和AutowiredMethodElement的重寫方法)
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
//**如果是欄位,直接設定欄位的值
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
//**getResourceToInject(target, requestingBeanName)獲取注入的bean
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
//**如果已經注入,則跳過
if (checkPropertySkipping(pvs)) {
return;
}
//**如果是方法,呼叫方法
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
//**getResourceToInject(target, requestingBeanName)獲取注入的bean
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
//**檢查是否已經注入
protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {
Boolean skip = this.skip;
if (skip != null) {
return skip;
}
if (pvs == null) {
this.skip = false;
return false;
}
synchronized (pvs) {
skip = this.skip;
if (skip != null) {
return skip;
}
if (this.pd != null) {
//**包含在已經處理過的集合(processedProperties)中,則返回true
if (pvs.contains(this.pd.getName())) {
this.skip = true;
return true;
}
//**否則,在已經處理過的集合中註冊,並返回false
else if (pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
}
}
this.skip = false;
return false;
}
}
//**清除已經注入的member
protected void clearPropertySkipping(@Nullable PropertyValues pvs) {
if (pvs == null) {
return;
}
synchronized (pvs) {
if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
}
}
}
//**獲取注入的物件,這裡返回null,需用子類實現
@Nullable
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
return null;
}
...equals and hashCode and toString方法
}
}
3.AutowiredAnnotationBeanPostProcessor(自動裝配處理器)
注意(重點)
A.處理邏輯
- 首先處理@Lookup註解並獲取候選的建構函式(包括父類上的@Lookup)。注意,這裡只是選擇了匹配的建構函式,有可能有多個,具體呼叫哪個建構函式邏輯在ConstructorResolver.autowireConstructor(),不在本篇深究;
- 然後把依賴spring注入的member資訊註冊到RootBeanDefinition的externallyManagedConfigMembers(spring管理的配置成員集合);
- 最後把bean及其依賴注入的bean的關係註冊到DefaultSingletonBeanRegistryt的dependentBeanMap和dependenciesForBeanMap。然後設定注入的值(如果是欄位,直接賦值,如果是方法,呼叫方法);
B.自定義自動裝配註解
自定一個自動裝配註解@MyAutowired,功能同解@Autowired
//1.自定義解@MyAutowired註解
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowired {
//**required引數名也可以自定義
boolean required() default true;
}
//2.使MyAutowired註解生效
@Component
public class MyAutowiredAnnotationBeanPostProcessor extends AutowiredAnnotationBeanPostProcessor {
public MyAutowiredAnnotationBeanPostProcessor(){
super.setAutowiredAnnotationTypes(Set.of(Autowired.class, Value.class, MyAutowired.class));
}
}
//3.使用示例
@Component
public class MyAutowiredDemo {
@MyAutowired
private User user;
public void hello(){
System.out.println(user.getClass());
}
}
C.處理規則
構造方法注入:
- 如果required=true,只能標註一個@Autowired
- 如果required=false,可標註多個@Autowired,且匹配項最多的建構函式會生效
- 如果沒有匹配到任何一個建構函式,則預設的建構函式會生效
- 如果只有一個建構函式,則這個建構函式會生效(無論有沒有標註@Autowired)
- 建構函式不需要為public
欄位注入:
- 欄位在構造方法注入之後,在配置方法注入之前呼叫
- 欄位不需要為public
方法注入
- 配置方法可以有任意名稱和任意數量的引數,spring會從容器中匹配並注入這些引數
- setter方法是配置方法的特例,spring並沒有要求配置方法一定是setter方法
- 配置方法不需要為public
xml配置注入
- 預設情況下,AutowiredAnnotationBeanPostProcessor會註冊context:annotation-config和context:component-scan標籤
- 可指定自定義的AutowiredAnnotationBeanPostProcessor刪除或者關閉預設的註解配置
- 注意:註解注入會在xml注入之前執行。後一種配置會覆蓋前一種配置
Lookup方法
- @Lookup會在執行查詢需要注入的引數(如果引數不是單例的,這會很有用。等同型別安全的getBean方法)
原始碼
- InstantiationAwareBeanPostProcessorAdapter:SmartInstantiationAwareBeanPostProcessor(智慧例項化處理器)介面介面卡(空實現),其子類只需要實現關注的方法,而不用把所有的方法都實現;
- MergedBeanDefinitionPostProcessor:合併Bean定義後置處理器;
- PriorityOrdered:優先的Ordered序列,PriorityOrdered優先順序總是在Ordered之前(無論order值是多少);
- BeanFactoryAware:獲取spring上下文中的BeanFactory;
- 執行順序:
- BeanFactory.setBeanFactory()
- PriorityOrdered.getOrder()
- InstantiationAwareBeanPostProcessorAdapter.determineCandidateConstructors():處理@Lookup註解並獲取候選的建構函式(包括父類上的@Lookup);
- MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition():註冊需要注入的member;
- InstantiationAwareBeanPostProcessorAdapter.postProcessProperties():執行注入bean的邏輯(包括父類上的注入註解);
- MergedBeanDefinitionPostProcessor.resetBeanDefinition():重置bean定義後,在快取中刪除注入資料;
/**
* 實現自動裝配:註解,欄位,setter方法和配置方法
* 通過註解檢測需要注入的成員。預設註解包括@Autowired和@Value,並且支援JSR-330的@Inject(同@Autowired)
*
* 構造方法注入:
* 如果required=true,只能標註一個@Autowired
* 如果required=false,可標註多個@Autowired,且匹配項最多的建構函式會生效
* 如果沒有匹配到任何一個建構函式,則預設的建構函式會生效
* 如果只有一個建構函式,則這個建構函式會生效(無論有沒有標註@Autowired)
* 建構函式不需要為public
*
* 欄位注入:
* 欄位在構造方法注入之後,在配置方法注入之前呼叫
* 欄位不需要為public
*
* 方法注入
* 配置方法可以有任意名稱和任意數量的引數,spring會從容器中匹配並注入這些引數
* setter方法是配置方法的特例,spring並沒有要求配置方法一定是setter方法
* 配置方法不需要為public
*
* xml配置注入
* 預設情況下,AutowiredAnnotationBeanPostProcessor會註冊context:annotation-config和context:component-scan標籤
* 可指定自定義的AutowiredAnnotationBeanPostProcessor刪除或者關閉預設的註解配置
*
* 注意:註解注入會在xml注入之前執行。後一種配置會覆蓋前一種配置
*
* Lookup方法
* @Lookup會在執行查詢需要注入的引數(如果引數不是單例的,這會很有用。等同型別安全的getBean方法)
*/
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
//**處理的注入註解
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
//**表示required引數的引數名
private String requiredParameterName = "required";
//**表示required引數的預設值
private boolean requiredParameterValue = true;
//**預設的執行順序
private int order = Ordered.LOWEST_PRECEDENCE - 2;
//**beanFactory
@Nullable
private ConfigurableListableBeanFactory beanFactory;
//**快取處理過@Lookup註解的bean名稱
private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
//**快取指定類候選的建構函式
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);
//**快取注入的後設資料
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
//**預設處理的自動裝配註解為@Autowired和@Value,並且支援@Inject
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
//**指定處理的自動裝配註解
public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.add(autowiredAnnotationType);
}
//**指定多個處理的自動裝配註解
public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
this.autowiredAnnotationTypes.clear();
this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
}
//**指定表示required引數的引數名
public void setRequiredParameterName(String requiredParameterName) {
this.requiredParameterName = requiredParameterName;
}
//**指定表示required引數的引數值
public void setRequiredParameterValue(boolean requiredParameterValue) {
this.requiredParameterValue = requiredParameterValue;
}
//**設定執行順序
public void setOrder(int order) {
this.order = order;
}
//**實現PriorityOrdered,獲取執行順序
@Override
public int getOrder() {
return this.order;
}
//**實現BeanFactoryAware,獲取beanFactory
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
}
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
//**實現MergedBeanDefinitionPostProcessor
//**如果存在需要注入的member,則註冊到externallyManagedConfigMembers(spring管理的配置成員集合)
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//**獲取注入後設資料
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
//**如果存在需要注入的member,把注入元素註冊到externallyManagedConfigMembers(spring管理的配置成員集合)
metadata.checkConfigMembers(beanDefinition);
}
//**實現MergedBeanDefinitionPostProcessor,重置bean定義後,在快取中刪除注入資料;
@Override
public void resetBeanDefinition(String beanName) {
this.lookupMethodsChecked.remove(beanName);
this.injectionMetadataCache.remove(beanName);
}
//**實現InstantiationAwareBeanPostProcessorAdapter,處理@Lookup註解並獲取候選的建構函式
//**如果required=true,則只能有一個候選建構函式
//**如果required=false,則全部都為候選建構函式
//**如果只有一個建構函式且包含引數,則這個建構函式為候選建構函式(無論有沒有標註@Autowired)
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
//**處理當前類及其父類@Lookup註解(spring會動態生成子類並重寫/實現被註解的方法),並快取到lookupMethodsChecked中
if (!this.lookupMethodsChecked.contains(beanName)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
this.lookupMethodsChecked.add(beanName);
}
//**從快取中獲取當前類的候選建構函式
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
//**快取中不存在,則獲取
if (candidateConstructors == null) {
//**加鎖
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
//**獲取所有建構函式
Constructor<?>[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
//**存放候選建構函式
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
//**required=true的建構函式
Constructor<?> requiredConstructor = null;
//**預設的無參建構函式
Constructor<?> defaultConstructor = null;
//**Kotlin中的primary建構函式,java直接返回null
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
//**非Synthetic建構函式的數量(synthetic是由編譯器引入的建構函式,主要用於JVM內部使用)
int nonSyntheticConstructors = 0;
//**遍歷所有建構函式
for (Constructor<?> candidate : rawCandidates) {
//**記錄非Synthetic建構函式的數量
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
//**java這裡為null
else if (primaryConstructor != null) {
continue;
}
//**查詢是否包含@Autowired和@Value等注入註解
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
//**如果不包含注入註解,則獲取當前類的使用者類(如果當前類為spring生成的動態代理類,則會獲取到當前類代理的類)建構函式的注入註解
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
//**如果包含注入註解,驗證如果required=true時只能標註一個@Autowired,並新增到候選建構函式集合中
if (ann != null) {
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//**獲取當前建構函式required的值
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
else if (candidate.getParameterCount() == 0) { //**否則如果引數為0,則為預設建構函式
defaultConstructor = candidate;
}
}
//**如果候選建構函式不為空,並且required=true的建構函式為空,則把預設建構函式新增到候選建構函式集合中
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
//**如果只有一個建構函式,則這個建構函式會生效(無論有沒有標註@Autowired)
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//**針對Kotlin中的primary建構函式
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else { //**否則返回空建構函式陣列
candidateConstructors = new Constructor<?>[0];
}
//**快取到candidateConstructorsCache中
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
//**實現InstantiationAwareBeanPostProcessorAdapter.postProcessProperties(),執行注入bean的邏輯
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//**獲取當前bean的注入後設資料
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {//**執行注入(欄位使用使用AutowiredFieldElement.inject(),方法使用AutowiredMethodElement的.inject())
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
//**過時,以postProcessProperties為準
@Deprecated
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
return postProcessProperties(pvs, bean, beanName);
}
//**指定bean的注入,邏輯基本和postProcessProperties一樣,執行專案沒發現有呼叫
public void processInjection(Object bean) throws BeanCreationException {
Class<?> clazz = bean.getClass();
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
try {
metadata.inject(bean, null, null);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
"Injection of autowired dependencies failed for class [" + clazz + "]", ex);
}
}
//**獲取指定bean的注入後設資料
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
//**從快取中獲取注入後設資料
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//**如果metadata為空,則重新構造metadata,如果metadata的目標類不是傳入的clazz,則清除注入資料,然後重新構造metadata
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//**構造metadata
metadata = buildAutowiringMetadata(clazz);
//**快取到injectionMetadataCache中
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
//**構造指定類及其父類的注入後設資料
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
//**如果不包含注入註解,則返回空注入後設資料
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
//**存放類的所有注入元素
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
//**遍歷獲取類及其父類的注入元素
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//**遍歷獲取類的欄位注入元素
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
//**不支援靜態欄位
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//**獲取required的值
boolean required = determineRequiredStatus(ann);
//**建立注入元素並存放到currElements中
currElements.add(new AutowiredFieldElement(field, required));
}
});
//**遍歷獲取類的方法注入元素
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//**如果方法是編譯器引入橋接方法,則跳過
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
//**如果方法包含注入註解 && 屬於指定clazz類(繼承的方法也算)
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
//**不支援靜態方法
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
//**沒有引數,則跳過
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
//**獲取required的值
boolean required = determineRequiredStatus(ann);
//**獲取方法的屬性描述器
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
//**建立注入元素並存放到currElements中
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
//**建立注入後設資料
return InjectionMetadata.forElements(elements, clazz);
}
//**查詢member上的注入註解
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
//**獲取注入配置的required的值
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
//**過時,獲取注入配置的required的值
@Deprecated
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
return (!ann.containsKey(this.requiredParameterName) ||
this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}
//**根據類物件查詢注入的候選bean
protected <T> Map<String, T> findAutowireCandidates(Class<T> type) throws BeansException {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory configured - " +
"override the getBeanOfType method or specify the 'beanFactory' property");
}
return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
}
//**註冊bean及其依賴注入的bean
private void registerDependentBeans(@Nullable String beanName, Set<String> autowiredBeanNames) {
if (beanName != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName +
"' to bean named '" + autowiredBeanName + "'");
}
}
}
}
//**解析指定的快取方法引數/欄位值
@Nullable
private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) {
if (cachedArgument instanceof DependencyDescriptor) {
DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
Assert.state(this.beanFactory != null, "No BeanFactory available");
return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
}
else {
return cachedArgument;
}
}
//**注入元素(描述每個依賴spring注入的欄位相關資訊)
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
//**required
private final boolean required;
//**是否已經快取欄位注入的值
private volatile boolean cached = false;
//**快取欄位注入的值
@Nullable
private volatile Object cachedFieldValue;
public AutowiredFieldElement(Field field, boolean required) {
super(field, null);
this.required = required;
}
//**注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) { //**如果已經快取欄位注入的值,則直接從快取中解析
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
//**獲取注入的bean
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//**如果是@value獲取配置的引數值,則此處獲取的是配置的值,autowiredBeanNames會為空
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) { //**同步
if (!this.cached) {
if (value != null || this.required) { //**如果注入的bean存在 || required = true
this.cachedFieldValue = desc; //**快取注入的bean
//**註冊bean及其依賴注入的bean
registerDependentBeans(beanName, autowiredBeanNames);
//**如果匹配的依賴bean只有一個,則封裝為ShortcutDependencyDescriptor,並快取
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
//**通過反射賦值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
//**注入元素(描述每個依賴spring注入的方法相關資訊)
private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
//**required
private final boolean required;
//**是否已經快取方法注入的值
private volatile boolean cached = false;
//**快取方法注入的值
@Nullable
private volatile Object[] cachedMethodArguments;
public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
super(method, pd);
this.required = required;
}
//**注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//**如果已經注入,則跳過
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {//**如果已經快取方法注入的值,則直接從快取中解析
arguments = resolveCachedArguments(beanName);
}
else {
int argumentCount = method.getParameterCount();
arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
//**遍歷方法的所有引數,獲取注入的bean
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
//**如果是@value獲取配置的引數值,則此處獲取的是配置的值,autowiredBeanNames會為空
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {//**同步
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
//**註冊bean及其依賴注入的bean
registerDependentBeans(beanName, autowiredBeans);
//**如果每個引數匹配的依賴bean都只有一個,則封裝為ShortcutDependencyDescriptor,並快取
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
}
if (arguments != null) {
try {//**通過反射呼叫方法
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
//**遍歷解析快取引數
@Nullable
private Object[] resolveCachedArguments(@Nullable String beanName) {
Object[] cachedMethodArguments = this.cachedMethodArguments;
if (cachedMethodArguments == null) {
return null;
}
Object[] arguments = new Object[cachedMethodArguments.length];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = resolvedCachedArgument(beanName, cachedMethodArguments[i]);
}
return arguments;
}
}
//**注入依賴描述器
@SuppressWarnings("serial")
private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
private final String shortcut;
private final Class<?> requiredType;
public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class<?> requiredType) {
super(original);
this.shortcut = shortcut;
this.requiredType = requiredType;
}
@Override
public Object resolveShortcut(BeanFactory beanFactory) {
return beanFactory.getBean(this.shortcut, this.requiredType);
}
}
}
相關文章
- @ConfigurationProperties和@Value
- springMVC 的工作原理和機制SpringMVC
- camera理論基礎和工作原理
- Ingress-nginx工作原理和實踐Nginx
- Session工作原理和典型應用分析Session
- Oracle分析函式-first_value()和last_value()Oracle函式AST
- 容器的工作原理和隔離機制
- 圖解WebGL和Three.js工作原理圖解WebJS
- KubernetesAPIserver工作原理APIServer
- Mybatis工作原理MyBatis
- require工作原理UI
- HTTPS工作原理HTTP
- Nginx工作原理Nginx
- pr工作原理
- SpringMVC工作原理SpringMVC
- 搞懂Redis RDB和AOF持久化及工作原理Redis持久化
- redis自學(33)哨兵的作用和工作原理Redis
- servlet的生命週期和工作原理介紹Servlet
- Oracle DUL的工作原理和技術實現Oracle
- MT7686處理器特點和工作原理
- 一文讀懂DHCP的工作原理和作用
- 交換機的作用、功能和工作原理詳解
- Mirror 的工作原理
- Web Scraper工作原理Web
- 【MySQL】Mydumper工作原理MySql
- LiveData的工作原理LiveData
- OAuth的工作原理OAuth
- Spring Session工作原理SpringSession
- javascript引擎工作原理JavaScript
- Feign的工作原理
- ZStack基本工作原理
- pr工作原理文件
- Docker 工作原理分析Docker
- Spark的工作原理Spark
- textarea中的innerHtml,innerText和valueHTML
- hashMap 中key和value互換HashMap
- JavaScript的工作原理:引擎,執行時和呼叫堆疊JavaScript
- Redis主從複製工作原理和步驟介紹Redis