源碼分析:doCreateBean

spring的ioc創(chuàng)建bean的最核心代碼 我們來看看他具體做了啥 怎么做

整體的邏輯

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

    BeanWrapper 挪丢,包含了真正的bean對象和bean的class,以及PropertyDescriptor集合
        BeanWrapper instanceWrapper = null;
單例的情況下嘗試從factoryBeanInstanceCache獲取 instanceWrapper 
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
如果沒有則需要自己創(chuàng)建
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
如果不是NullBean蹬刷,則將resolvedTargetType 屬性設(shè)置為當(dāng)前的WrappedClass
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

    這邊主要是尋找?guī)讉€meta,@PostConstruct,@Autowire,@Value,@Resource绸硕,@PreDestory等
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

如果當(dāng)前bean是單例,且支持循環(huán)依賴,且當(dāng)前bean正在創(chuàng)建巍糯,通過往singletonFactories添加一個objectFactory尝江,
這樣后期如果有其他bean依賴該bean 可以從singletonFactories獲取到bean涉波,getEarlyBeanReference可以對返回的bean進(jìn)行修改,這邊目前除了可能會返回動態(tài)代理對象 其他的都是直接返回bean
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        
        Object exposedObject = bean;
        try {
填充bean的屬性
            populateBean(beanName, mbd, instanceWrapper);
初始化bean
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }
如果earlySingletonExposure炭序,嘗試從緩存獲取該bean(一般存放在singletonFactories對象通過調(diào)用getObject 把對象存入earlySingletonObjects)啤覆,分別從singletonObjects和earlySingletonObjects獲取對象
        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
如果獲取到對象了
            if (earlySingletonReference != null) {
當(dāng)exposedObject (初始化之后的bean等于原始的bean,說明不是proxy)惭聂,則把緩存中的bean賦值給exposedObject 
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
檢測該bean的dependon的bean是否都已經(jīng)初始化好了
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        
        try {
注冊DisposableBean
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

createBeanInstance的源碼分析

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    獲取beanclass
        Class<?> beanClass = resolveBeanClass(mbd, beanName);
如果beanclass為空窗声,且beanclass不是public 且沒有權(quán)限訪問構(gòu)造函數(shù)和方法則拋出異常
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }
Supplier類似于factoryBean,然后從Supplier.get()的bean辜纲,并把bean包裝成BeanWrapper笨觅,然后初始化BeanWrapper
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
嘗試從factoryMethod獲取instanceSupplier
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        這邊是相當(dāng)于檢測是否曾經(jīng)創(chuàng)建過這個bean,如果是查看下具體采用哪個方法
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
說明曾經(jīng)解析過構(gòu)造函數(shù)或者factoryMethod
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
如果autowireNecessary為true說明是采用構(gòu)造函數(shù)注入
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
如果已經(jīng)解析過了則按照邏輯選擇
        if (resolved) {
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

    說明是第一次創(chuàng)建該bean   根據(jù)SmartInstantiationAwareBeanPostProcessor獲取構(gòu)造函數(shù)侨歉,目前看基本上都是空的實(shí)現(xiàn)屋摇,除了AutowiredAnnotationBeanPostProcessor
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
開始生成實(shí)例
            return autowireConstructor(beanName, mbd, ctors, args);
        }

采用普通的方式生成實(shí)例
        return instantiateBean(beanName, mbd);
    }
AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors

尋找被@Autowired的構(gòu)造函數(shù),如果沒有就返回null


我們的lookup就是在這邊通過反射發(fā)現(xiàn)的(其他的xml形式的replace-method和lookup在BeanDefinitionParserDelegate中)
        if (!this.lookupMethodsChecked.contains(beanName)) {
            try {
                ReflectionUtils.doWithMethods(beanClass, method -> {
                    Lookup lookup = method.getAnnotation(Lookup.class);
                    if (lookup != null) {
                        Assert.state(beanFactory != null, "No BeanFactory available");
                        LookupOverride override = new LookupOverride(method, lookup.value());
                        try {
                            RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
                            mbd.getMethodOverrides().addOverride(override);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(beanName,
                                "Cannot apply @Lookup to beans without corresponding bean definition");
                        }
                    }
                });
            }
            catch (IllegalStateException ex) {
                throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
            }
            this.lookupMethodsChecked.add(beanName);
        }

    檢測緩存中是否已經(jīng)存在對應(yīng)的構(gòu)造函數(shù)
        Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
        if (candidateConstructors == null) {
            雙重檢測
            synchronized (this.candidateConstructorsCache) {
                candidateConstructors = this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    Constructor<?>[] rawCandidates;
                    try {
獲取聲明的構(gòu)造函數(shù)
                        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;
這個只對Kotlin有用 對于java 一般默認(rèn)的返回null
                    Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                    int nonSyntheticConstructors = 0;
                    for (Constructor<?> candidate : rawCandidates) {
如果不是合成幽邓,則nonSyntheticConstructors加1
                        if (!candidate.isSynthetic()) {
                            nonSyntheticConstructors++;
                        }
                        else if (primaryConstructor != null) {
                            continue;
                        }
                        AnnotationAttributes ann = 
尋找構(gòu)造上是否存在@Autowired炮温,@Value,@Inject牵舵,如果存在就返回required=true柒啤,一個bean的構(gòu)造函數(shù)如果超過一個@Autowired就拋出異常
findAutowiredAnnotation(candidate);
如果沒有
                        if (ann == null) {
一般都是返回class本身倦挂,如果是cglib就返回原始的類
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            if (userClass != beanClass) {
                                try {
獲取帶有參數(shù)的構(gòu)造函數(shù)
                                    Constructor<?> superCtor =
                                            userClass.getDeclaredConstructor(candidate.getParameterTypes());
繼續(xù)尋找是否攜帶了上面三個注解
                                    ann = findAutowiredAnnotation(superCtor);
                                }
                                catch (NoSuchMethodException ex) {
                                    // Simply proceed, no equivalent superclass constructor found...
                                }
                            }
                        }
ann!=null 代表找到了
                        if (ann != null) {
如果requiredConstructor  不為null 說明重復(fù)定義
                            if (requiredConstructor != null) {
                                throw new BeanCreationException(beanName,
                                        "Invalid autowire-marked constructor: " + candidate +
                                        ". Found constructor with 'required' Autowired annotation already: " +
                                        requiredConstructor);
                            }
這邊只是確認(rèn)下required返回的是true還是false
                            boolean required = determineRequiredStatus(ann);
如果required是true
                            if (required) {
但是candidates不為空說明重復(fù)了
                                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;
                        }
                    }
                    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.isWarnEnabled()) {
                                logger.warn("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 {
                        candidateConstructors = new Constructor<?>[0];
                    }
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                }
            }
        }
        return (candidateConstructors.length > 0 ? candidateConstructors : null);
initBeanWrapper
初始BeanWrapperImpl担巩,設(shè)置ConversionService
(可以查看每個類型是否可以轉(zhuǎn)換成其他類型方援,并提供轉(zhuǎn)換的方法)和注冊
一些列的ResourceEditor到bw,比如    doRegisterEditor(registry, 
Resource.class, baseEditor);如果遇到Resource類型的使用baseEditor涛癌,進(jìn)
行編輯犯戏。
protected void initBeanWrapper(BeanWrapper bw) {
        bw.setConversionService(getConversionService());
        registerCustomEditors(bw);
    }

    protected void registerCustomEditors(PropertyEditorRegistry registry) {
        PropertyEditorRegistrySupport registrySupport =
                (registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
        if (registrySupport != null) {
            registrySupport.useConfigValueEditors();
        }
        if (!this.propertyEditorRegistrars.isEmpty()) {
            for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
                try {
                    registrar.registerCustomEditors(registry);
                }
                catch (BeanCreationException ex) {
                    Throwable rootCause = ex.getMostSpecificCause();
                    if (rootCause instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException) rootCause;
                        String bceBeanName = bce.getBeanName();
                        if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
                            if (logger.isDebugEnabled()) {
                                logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
                                        "] failed because it tried to obtain currently created bean '" +
                                        ex.getBeanName() + "': " + ex.getMessage());
                            }
                            onSuppressedException(ex);
                            continue;
                        }
                    }
                    throw ex;
                }
            }
        }
如果存在用戶自定義的類型轉(zhuǎn)換 也設(shè)置
        if (!this.customEditors.isEmpty()) {
            this.customEditors.forEach((requiredType, editorClass) ->
                    registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
        }
    }
MergedBeanDefinitionPostProcessors---AutowiredAnnotationBeanPostProcessor
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
獲取@Autowired注解的屬性
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
校驗(yàn)
        metadata.checkConfigMembers(beanDefinition);
    }


private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    獲取cacheKey
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());

        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
如果metadata為空,或者clazz拳话!=metadata.targetClass則說明沒有緩存無效先匪,重新buildAutowiringMetadata,然后把結(jié)果緩存起來
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
分別從class的field和method獲取@Autowired弃衍,并放入緩存(會迭代查詢其父類class)
                    metadata = buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }





public void checkConfigMembers(RootBeanDefinition beanDefinition) {
        Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
        for (InjectedElement element : this.injectedElements) {
把method或者field放入externallyManagedConfigMembers緩存中
            Member member = element.getMember();
            if (!beanDefinition.isExternallyManagedConfigMember(member)) {
                beanDefinition.registerExternallyManagedConfigMember(member);
                checkedElements.add(element);
                if (logger.isDebugEnabled()) {
                    logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
                }
            }
        }
        this.checkedElements = checkedElements;
    }


填充屬性-populateBean--先對于unsatisfiedNonSimpleProperties(未在xml配置該property 該property是一個特殊的對象(普通的javabean的類))屬性進(jìn)行處理呀非,在對一些注解注入的屬性處理,最終對自動注入的屬性(即包含set方法的)屬性進(jìn)行處理
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
如果實(shí)力為空但是還有屬性镜盯,拋出異常
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
        直接返回
                return;
            }
        }

    
        boolean continueWithPropertyPopulation = true;
這邊主要是根據(jù)InstantiationAwareBeanPostProcessor 判斷是否繼續(xù)給該bean配置屬性
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }
設(shè)置PropertyValues 
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
如果該bean是支持按照名字或者類型自動注入的岸裙,
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
深度拷貝PropertyValues,當(dāng)然對于對象來說只能公用一個
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

    按照名稱開始注入(這邊不是真正的注入速缆,只是尋找可注入的bean)
必須有set方法
必須不能是忽略的類型或者接口
spring配置的properties中沒有改屬性
該屬性不能是 a primitive, an enum, a String or other CharSequence, a Number, a Date,
     * a URI, a URL, a Locale or a Class.
     其中primitive( boolean, byte,
     * char, short, int, long, float, or double)或者其包裝類
     如果class是array 其元素也不能是上述屬性
     -------
     
     也就是說自動注入的時候 如果不顯示的配置<properties> 對于非對象的類型是不會注入的降允,但是對于對象是會主動去尋找的
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

按照類型開始注入(這邊不是真正的注入,只是尋找可注入的bean)
必須有set方法
必須不能是忽略的類型或者接口
spring配置的properties中沒有改屬性
該屬性不能是 a primitive, an enum, a String or other CharSequence, a Number, a Date,
     * a URI, a URL, a Locale or a Class.
     其中primitive( boolean, byte,
     * char, short, int, long, float, or double)或者其包裝類
     如果class是array 其元素也不能是上述屬性
     -------
     
     也就是說自動注入的時候 如果不顯示的配置<properties> 對于非對象的類型是不會注入的艺糜,但是對于對象是會主動去尋找的
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
如果存在InstantiationAwareBeanPostProcessors或者有依賴檢測
        if (hasInstAwareBpps || needsDepCheck) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
獲得一組PropertyDescriptor拟糕,filterPropertyDescriptorsForDependencyCheck
---獲取該bean下面的所有屬性和方法
---刪除如果是cglib的本身的屬性和方法
---刪除如果是ignoredDependencyTypes
---刪除如果是set方法且需要忽略的(即實(shí)現(xiàn)了xxawared接口的)也需要刪除
---最終保留的屬性可以自動注入
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
對@Autowired,@Resource等屬性的注入
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
依賴檢測
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }
對自動注入的時候 set方法的注入
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

初始化bean-initializeBean

第一種:通過@PostConstruct 和 @PreDestroy 方法 實(shí)現(xiàn)初始化和銷毀bean之前進(jìn)行的操作

第二種是:通過 在xml中定義init-method 和 destory-method方法

第三種是: 通過bean實(shí)現(xiàn)InitializingBean和 DisposableBean接口
三種銷毀方式都是把bean轉(zhuǎn)換成DisposableBean

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
首先調(diào)用回調(diào)方法xxxaware
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
調(diào)用spring的擴(kuò)展點(diǎn) 在初始化之前調(diào)用
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
先調(diào)用InitializingBean的afterPropertiesSet,在調(diào)用我們定義的init方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
調(diào)用spring的擴(kuò)展點(diǎn) 在初始化之后調(diào)用倦踢,注意這邊就是生成我們配置的動態(tài)代理對象的關(guān)鍵代碼
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
注冊registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
只有非原型且是DisposableBean,或者有destroy method  或者注冊了 DestructionAwareBeanPostProcessors.
最終在緩存中存放beanName和DisposableBean的映射關(guān)系侠草,然后注冊鉤子的時候調(diào)用
        if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
針對單例或者scope注冊
            if (mbd.isSingleton()) {
    最終在緩存中存放beanName和DisposableBean的映射關(guān)系辱挥,然后注冊鉤子的時候調(diào)用
                registerDisposableBean(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
            else {
                // A bean with a custom scope...
                Scope scope = this.scopes.get(mbd.getScope());
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
                }
注冊了一個回調(diào),根據(jù)scope的類型(比如是一個線程边涕,一個request晤碘,servlet,事務(wù))當(dāng)這幾種結(jié)束的時候回調(diào)這個DisposableBeanAdapter的destory方法
                scope.registerDestructionCallback(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
        }
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末功蜓,一起剝皮案震驚了整個濱河市园爷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌式撼,老刑警劉巖童社,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異著隆,居然都是意外死亡扰楼,警方通過查閱死者的電腦和手機(jī)呀癣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弦赖,“玉大人项栏,你說我怎么就攤上這事〉攀” “怎么了沼沈?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長币厕。 經(jīng)常有香客問我列另,道長,這世上最難降的妖魔是什么劈榨? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任访递,我火速辦了婚禮,結(jié)果婚禮上同辣,老公的妹妹穿的比我還像新娘拷姿。我一直安慰自己,他們只是感情好旱函,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布响巢。 她就那樣靜靜地躺著,像睡著了一般棒妨。 火紅的嫁衣襯著肌膚如雪踪古。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天券腔,我揣著相機(jī)與錄音伏穆,去河邊找鬼。 笑死纷纫,一個胖子當(dāng)著我的面吹牛枕扫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辱魁,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼烟瞧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了染簇?” 一聲冷哼從身側(cè)響起参滴,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锻弓,沒想到半個月后砾赔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年过蹂,在試婚紗的時候發(fā)現(xiàn)自己被綠了十绑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡酷勺,死狀恐怖本橙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情脆诉,我是刑警寧澤甚亭,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站击胜,受9級特大地震影響亏狰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偶摔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一暇唾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辰斋,春花似錦策州、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至藕夫,卻和暖如春孽糖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背毅贮。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工办悟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滩褥。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓誉尖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铸题。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345