populateBean方法解析

populateBean 方法實現的功能

poppulateBean作用

autowired 解析

Autowired 實例,code 如下:

package com.gientech.populateBean.annotation;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class BookController {

    @Autowired
    private BookService service;
}

package com.gientech.populateBean.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookService {

    @Autowired
    private BookDao dao;

}

package com.gientech.populateBean.annotation;

import org.springframework.stereotype.Repository;

@Repository
public class BookDao {
}

bookcontroller初始化完成時,只在堆中開闢了存儲空間,屬性都沒有賦值,內存截圖如下:
初始化完成截圖

給屬性bookservice賦值時,此時bookservice 還沒有對象生成,此時,屬性有@Autowired註解,由AutowiredAnnotationBeanPostProcessor.java解析autowired註解,生成bookservice對象。解析過程中內存截圖如下:
解析autowired內存截圖

生成過程如下。
解析autowired

自定義@Myautowired註解

實現自定義@Myautowired 註解,功能與@Autowired 註解相同,code 如下:

package com.gientech.selfAutowired;


import java.lang.annotation.*;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowired {
    boolean required() default true;
}

package com.gientech.selfAutowired;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.support.LookupOverride;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class MyAutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    protected final Log logger = LogFactory.getLog(getClass());

    // 該處理器支持解析的註解們,默認支持的是3個
    private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);

    // @Autowired(required = false)這個註解的屬性值名稱
    private String requiredParameterName = "required";

    // 這個值一般請不要改變(若改成false,效果required = false的作用是相反的了)
    private boolean requiredParameterValue = true;

    private int order = Ordered.LOWEST_PRECEDENCE - 2;

    @Nullable
    private ConfigurableListableBeanFactory beanFactory;

    // 對@Lookup方法的支持
    private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

    // 構造函數候選器緩存
    private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);

    // 方法注入、字段filed注入
    // 此處InjectionMetadata這個類非常重要,到了此處@Autowired註解含義已經沒有了,完全被準備成這個元數據了
    // InjectionMetadata持有targetClass、Collection<InjectedElement> injectedElements等兩個重要屬性
    // 其中InjectedElement這個抽象類最重要的兩個實現爲:AutowiredFieldElement和AutowiredMethodElement
    private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);


    /**
     * 構造方法,完成對應註解的注入
     *
     * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
     * standard {@link Autowired @Autowired} and {@link Value @Value} annotations.
     * <p>Also supports JSR-330's {@link  @Inject} annotation,
     * if available.
     */
    @SuppressWarnings("unchecked")
    public MyAutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(MyAutowired.class);
    }


    /**
     * 自定義支持的依賴注入註解類型
     *
     * Set the 'autowired' annotation type, to be used on constructors, fields,
     * setter methods, and arbitrary config methods.
     * <p>The default autowired annotation types are the Spring-provided
     * {@link Autowired @Autowired} and {@link Value @Value} annotations as well
     * as JSR-330's {@link  @Inject} annotation, if available.
     * <p>This setter property exists so that developers can provide their own
     * (non-Spring-specific) annotation type to indicate that a member is supposed
     * to be autowired.
     */
    public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
        Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
        this.autowiredAnnotationTypes.clear();
        this.autowiredAnnotationTypes.add(autowiredAnnotationType);
    }

    /**
     * Set the 'autowired' annotation types, to be used on constructors, fields,
     * setter methods, and arbitrary config methods.
     * <p>The default autowired annotation types are the Spring-provided
     * {@link Autowired @Autowired} and {@link Value @Value} annotations as well
     * as JSR-330's {@link  @Inject} annotation, if available.
     * <p>This setter property exists so that developers can provide their own
     * (non-Spring-specific) annotation types to indicate that a member is supposed
     * to be autowired.
     */
    public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
        Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
        this.autowiredAnnotationTypes.clear();
        this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
    }

    /**
     * Set the name of an attribute of the annotation that specifies whether it is required.
     * @see #setRequiredParameterValue(boolean)
     */
    public void setRequiredParameterName(String requiredParameterName) {
        this.requiredParameterName = requiredParameterName;
    }

    /**
     * Set the boolean value that marks a dependency as required.
     * <p>For example if using 'required=true' (the default), this value should be
     * {@code true}; but if using 'optional=false', this value should be {@code false}.
     * @see #setRequiredParameterName(String)
     */
    public void setRequiredParameterValue(boolean requiredParameterValue) {
        this.requiredParameterValue = requiredParameterValue;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    // bean工廠必須是ConfigurableListableBeanFactory的
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException(
                    "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
        }
        this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
    }


    /**
     * 處理合並的bean定義信息
     * 1、解析@Autowired等註解然後轉換
     * 2、把註解信息轉換爲InjectionMetadata然後緩存到上面的injectionMetadataCache裏面
     * @param beanDefinition the merged bean definition for the bean
     * @param beanType the actual type of the managed bean instance
     * @param beanName the name of the bean
     */
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 解析註解並緩存
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }

    @Override
    public void resetBeanDefinition(String beanName) {
        this.lookupMethodsChecked.remove(beanName);
        this.injectionMetadataCache.remove(beanName);
    }

    /**
     * 獲取構造器集合
     * 		如果有多個Autowired,required爲true,不管有沒有默認構造方法,會報異常
     * 		如果只有一個Autowired,required爲false,沒有默認構造方法,會報警告
     * 		如果沒有Autowired註解,定義了兩個及以上有參數的構造方法,沒有無參構造方法,且不是通過xml配置文件進行加載,使用@Component進行加載就會報錯
     * 		其他情況都可以,但是以有Autowired的構造方法優先,然後纔是默認構造方法
     *
     *
     * @param beanClass
     * @param beanName
     * @return
     * @throws BeanCreationException
     */
    @Override
    @Nullable
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
            throws BeanCreationException {

        // Let's check for lookup methods here...
        // 處理包含@Loopup註解的方法,如果集合中沒有beanName,則走一遍bean中的所有方法,過濾是否含有lookup方法
        if (!this.lookupMethodsChecked.contains(beanName)) {
            if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
                try {
                    Class<?> targetClass = beanClass;
                    do {
                        // 遍歷當前類以及所有父類,找出lookup註解的方法進行處理
                        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                            // 獲取method上的Lookup註解
                            Lookup lookup = method.getAnnotation(Lookup.class);
                            // 存在此註解的話,就將方法和註解中的內容構建LookupOverride對象,設置進BeanDefinition中
                            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();
                    }
                    //遍歷父類,直到Object
                    while (targetClass != null && targetClass != Object.class);

                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
                }
            }
            // 無論對象中是否含有@Lookup方法,過濾完成後都會放到集合中,證明此bean已經檢查完@Lookup註解
            this.lookupMethodsChecked.add(beanName);
        }

        // Quick check on the concurrent map first, with minimal locking.
        // 從緩存中拿構造函數,不存在的話就進入代碼塊中再拿一遍,還不存在的話就進行下方的邏輯,
        Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
        // 沒找到再同步
        if (candidateConstructors == null) {
            // Fully synchronized resolution now...
            synchronized (this.candidateConstructorsCache) {
                //再檢測一遍,雙重檢測
                candidateConstructors = this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    Constructor<?>[] rawCandidates;
                    try {
                        //獲取bean中所有的構造函數
                        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);
                    // 帶有依賴項的構造函數
                    Constructor<?> requiredConstructor = null;
                    // 默認使用的構造函數
                    Constructor<?> defaultConstructor = null;
                    // 獲取主構造函數
                    Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                    // 標識,表示不是合成構造函數的數量
                    // 合成構造函數->有方法參數並對實例進行賦值的構造函數
                    int nonSyntheticConstructors = 0;
                    // 遍歷所有的構造函數
                    for (Constructor<?> candidate : rawCandidates) {
                        // 構造函數不是合成構造函數,標識累加
                        if (!candidate.isSynthetic()) {
                            nonSyntheticConstructors++;
                        }
                        else if (primaryConstructor != null) {
                            continue;
                        }
                        // 查找構造函數上@Autowired註解的屬性,
                        MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                        // 註解不存在,則再通過方法獲取用戶類,如果是用戶類則返回用戶類,還判斷了cglib的情況,cglib情況則返回目標類
                        // 然後獲取參數一致的構造函數再獲取註解
                        if (ann == null) {
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            // 如果是有代理的,找到被代理
                            if (userClass != beanClass) {
                                try {
                                    // 獲取構造方法
                                    Constructor<?> superCtor =
                                            userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                    //繼續尋找Autowired和value的註解
                                    ann = findAutowiredAnnotation(superCtor);
                                }
                                catch (NoSuchMethodException ex) {
                                    // Simply proceed, no equivalent superclass constructor found...
                                }
                            }
                        }
                        // 構造函數上存在註解
                        if (ann != null) {
                            //有兩個Autowired註解,衝突了
                            if (requiredConstructor != null) {
                                throw new BeanCreationException(beanName,
                                        "Invalid autowire-marked constructor: " + candidate +
                                                ". Found constructor with 'required' Autowired annotation already: " +
                                                requiredConstructor);
                            }
                            // 獲取@Autowired註解中required屬性的值
                            boolean required = determineRequiredStatus(ann);
                            // 爲true則將這個構造函數設置爲帶有依賴項的構造函數並進行判斷,不可存在多個帶有依賴項的構造函數
                            if (required) {
                                //如果已經有required=false了,又來了一個required=true的方法就報異常了,這樣兩個可能就不知道用哪個了
                                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) {
                            defaultConstructor = candidate;
                        }
                    }
                    // 存在@Autowired註解的函數,並且required值爲false,則此註解不起作用,但是存在默認構造函數
                    // 則將默認構造函數添加到集合中,並將集合變爲數組使用
                    if (!candidates.isEmpty()) {
                        // Add default constructor to list of optional constructors, as fallback.
                        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]);
                    }
                    // 如果只存在一個構造函數,且這個構造函數有參數列表,則使用這個構造函數
                    else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                        //只有一個函數且有參數
                        candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
                    }
                    // 如果非合成構造存在兩個且有主構造和默認構造,且主構造和默認構造不相等,則這兩個一塊使用
                    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 {
                        //大於2個沒註解的構造方法就不知道要用什麼了,所以就返回null
                        candidateConstructors = new Constructor<?>[0];
                    }
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                }
            }
        }
        // 使用構造列表中沒有值,則返回null
        return (candidateConstructors.length > 0 ? candidateConstructors : null);
    }

    /**
     * 完成bean中@Autowired,@Inject,@Value註解的解析並注入的功能
     * @param pvs
     * @param bean
     * @param beanName
     * @return
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 從緩存中取出這個bean對應的依賴注入的元信息~
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {
            // 進行屬性注入
            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;
    }

    @Deprecated
    @Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {

        return postProcessProperties(pvs, bean, beanName);
    }

    /**
     * 'Native' processing method for direct calls with an arbitrary target instance,
     * resolving all of its fields and methods which are annotated with one of the
     * configured 'autowired' annotation types.
     * @param bean the target instance to process
     * @throws BeanCreationException if autowiring failed
     * @see #setAutowiredAnnotationTypes(Set)
     */
    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的依賴注入元信息,內部只要查找到了就會加入到緩存內,下次沒必要再重複查找了~
     * 	它是一個模版方法,真正做事的方法是:buildAutowiringMetadata,它複雜把標註有@Autowired註解的屬性轉換爲Metadata元數據信息,從而消除註解的定義
     * 	此處查找包括了字段依賴注入和方法依賴注入~~~
     * @param beanName
     * @param clazz
     * @param pvs
     * @return
     */
    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());
        // Quick check on the concurrent map first, with minimal locking.
        // 從緩存中獲取該類的信息
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        // 判斷是否需要刷新緩存
        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 = buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }

    /**
     * 去尋找有Autowired和Value註解的屬性和方法,也包括自定義的父類的,封裝成AutowiredMethodElement放入集合中
     * @param clazz
     * @return
     */
    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
        // 如果clazz是JDK中的類,直接忽略,因爲不可能標註有這些標註
        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<>();

            // 遍歷類中的每個屬性,判斷屬性是否包含指定的屬性(通過 findAutowiredAnnotation 方法)
            // 如果存在則保存,這裏注意,屬性保存的類型是 AutowiredFieldElement
            ReflectionUtils.doWithLocalFields(targetClass, field -> {
                MergedAnnotation<?> ann = findAutowiredAnnotation(field);
                if (ann != null) {
                    //Autowired註解不支持靜態方法
                    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.add(new MyAutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
                }
            });


            // 遍歷類中的每個方法,判斷屬性是否包含指定的屬性(通過 findAutowiredAnnotation 方法)
            // 如果存在則保存,這裏注意,方法保存的類型是 AutowiredMethodElement
            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
                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);
                        }
                    }
                    boolean required = determineRequiredStatus(ann);
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    // AutowiredMethodElement裏封裝了一個PropertyDescriptor(比字段多了一個參數)
                    currElements.add(new MyAutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));
                }
            });

            // 父類的都放在第一位,所以父類是最先完成依賴注入的
            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }
        while (targetClass != null && targetClass != Object.class);

        // InjectionMetadata就是對clazz和elements的一個包裝而已
        return InjectionMetadata.forElements(elements, clazz);
    }

    /**
     * 只要方法/屬性上但凡標註有一個註解,就立馬返回了
     * @param ao
     * @return
     */
    @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;
    }

    /**
     * Determine if the annotated field or method requires its dependency.
     * <p>A 'required' dependency means that autowiring should fail when no beans
     * are found. Otherwise, the autowiring process will simply bypass the field
     * or method when no beans are found.
     * @param ann the Autowired annotation
     * @return whether the annotation indicates that a dependency is 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())));
    }

    /**
     * Determine if the annotated field or method requires its dependency.
     * <p>A 'required' dependency means that autowiring should fail when no beans
     * are found. Otherwise, the autowiring process will simply bypass the field
     * or method when no beans are found.
     * @param ann the Autowired annotation
     * @return whether the annotation indicates that a dependency is required
     * @deprecated since 5.2, in favor of {@link #determineRequiredStatus(MergedAnnotation)}
     */
    @Deprecated
    protected boolean determineRequiredStatus(AnnotationAttributes ann) {
        return (!ann.containsKey(this.requiredParameterName) ||
                this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
    }

    /**
     * Obtain all beans of the given type as autowire candidates.
     * @param type the type of the bean
     * @return the target beans, or an empty Collection if no bean of this type is found
     * @throws BeansException if bean retrieval failed
     */
    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);
    }

    /**
     * Register the specified bean as dependent on the autowired beans.
     */
    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 + "'");
                }
            }
        }
    }

    /**
     * Resolve the specified cached method argument or field value.
     */
    @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;
        }
    }


    /**
     * Class representing injection information about an annotated field.
     */
    private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {

        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;
        }

        /**
         * 完成屬性的注入
         * @param bean
         * @param beanName
         * @param pvs
         * @throws Throwable
         */
        @Override
        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field) this.member;
            Object value;
            // 如果緩存,從緩存中獲取
            if (this.cached) {
                // 如果  cachedFieldValue instanceof DependencyDescriptor。則調用 resolveDependency 方法重新加載。
                value = resolvedCachedArgument(beanName, this.cachedFieldValue);
            }
            else {
                // 否則調用了 resolveDependency 方法。這個在前篇講過,在 populateBean 方法中按照類型注入的時候就是通過此方法,
                // 也就是說明了 @Autowired 和 @Inject默認是 按照類型注入的
                DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                desc.setContainingClass(bean.getClass());
                Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
                Assert.state(beanFactory != null, "No BeanFactory available");
                // 轉換器使用的bean工廠的轉換器
                TypeConverter typeConverter = beanFactory.getTypeConverter();
                try {
                    // 獲取依賴的value值的工作  最終還是委託給beanFactory.resolveDependency()去完成的
                    // 這個接口方法由AutowireCapableBeanFactory提供,它提供了從bean工廠裏獲取依賴值的能力
                    value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
                }
                // 把緩存值緩存起來
                synchronized (this) {
                    // 如果沒有緩存,則開始緩存
                    if (!this.cached) {
                        // 可以看到value!=null並且required=true纔會進行緩存的處理
                        if (value != null || this.required) {
                            // 這裏先緩存一下 desc,如果下面 utowiredBeanNames.size() > 1。則在上面從緩存中獲取的時候會重新獲取。
                            this.cachedFieldValue = desc;
                            // 註冊依賴bean
                            registerDependentBeans(beanName, autowiredBeanNames);
                            // autowiredBeanNames裏可能會有別名的名稱,所以size可能大於1
                            if (autowiredBeanNames.size() == 1) {
                                // beanFactory.isTypeMatch挺重要的,因爲@Autowired是按照類型注入的
                                String autowiredBeanName = autowiredBeanNames.iterator().next();
                                if (beanFactory.containsBean(autowiredBeanName) &&
                                        beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                    this.cachedFieldValue = new MyAutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(
                                            desc, autowiredBeanName, field.getType());
                                }
                            }
                        }
                        else {
                            this.cachedFieldValue = null;
                        }
                        this.cached = true;
                    }
                }
            }
            if (value != null) {
                // 通過反射,給屬性賦值
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }
    }


    /**
     * Class representing injection information about an annotated method.
     */
    private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {

        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;
        }

        /**
         * 完成方法的注入
         * @param bean
         * @param beanName
         * @param pvs
         * @throws Throwable
         */
        @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) {
                // Shortcut for avoiding synchronization...
                arguments = resolveCachedArguments(beanName);
            }
            else {
                // 獲取方法的參數,從Spring 容器中獲取(緩存中沒有則嘗試創建)
                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();
                // 遍歷參數從容器中獲取
                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 {
                        // 根據類型從容器中獲取
                        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);
                            registerDependentBeans(beanName, autowiredBeans);
                            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 MyAutowiredAnnotationBeanPostProcessor.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;
        }
    }


    /**
     * DependencyDescriptor variant with a pre-resolved target bean name.
     */
    @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);
        }
    }


}

package com.gientech.selfAutowired;

import org.springframework.stereotype.Controller;

@Controller
public class MyAutowiredController {

    @MyAutowired
    private MyAutowiredService service;

    public void show(){
        service.show();
    }

}

package com.gientech.selfAutowired;

import org.springframework.stereotype.Service;

@Service
public class MyAutowiredService {

    public void show(){
        System.out.println("Hello Gientech");
    }
}

package com.gientech.selfAutowired;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyAutowiredTest {

    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("selfAutowired.xml");
        MyAutowiredController controller = ac.getBean(MyAutowiredController.class);
        controller.show();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    

    <context:component-scan base-package="com.gientech.selfAutowired"></context:component-scan>

</beans>

運行結果如圖所示:
myautowiredresult

initializeBean方法內容

nitializeBean方法內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章