Spring-bean的分析

@Spring-Bean的創建和獲取

創建bean.xml來獲取bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="zxbean" class="com.zx.bean_xml.ZxBean"/>
</beans>
開始創建對象
public class ZxBean_Test {
    public static void main(String args[]){
        //獲取zxbean.xml
        ClassPathResource resource = new ClassPathResource("zxbean.xml");
        //初始化容器
        new XmlBeanDefinitionReader((BeanDefinitionRegistry) resource);
    }
}
初始化XmlBeanFactory
public class ZxXmlBeanFactory {
    //創建一個讀取bean的常量
    private final XmlBeanDefinitionReader reader;

    public ZxXmlBeanFactory(XmlBeanDefinitionReader reader) {
        this.reader = reader;
    }
    public ZxXmlBeanFactory(Resource resource) throws BeansException {
        this(resource, (BeanFactory)null);
    }

    public ZxXmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        //用XmlBeanDefinitionReader,來進行加載
        this.reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) this);
        //解析資源
        this.reader.loadBeanDefinitions(resource);
    }
}
點loadBeanDefinitions閱讀源碼

在這裏插入圖片描述
我們可以看到在這裏包裝成了EncodeResoures
然後繼續往下讀會發現轉化成了IO流
在這裏插入圖片描述

點doLoadBeanDefinitions,閱讀源碼

在這裏插入圖片描述

點擊這個註冊Bean的

在這裏插入圖片描述
從xml讀取bean
在這裏插入圖片描述
繼承了ReadContext
在這裏插入圖片描述


SpringIOC的加載過程

創建spring-bean.xml.

<bean id="person" class="com.zx.bean.Person.Person" scope="prototype">
        <property name="age" value="1"/>
        <property name="name" value="zhangsan"/>
    </bean>

寫一個測試類

public class Test {
        public static void main(String args[]){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println("name"+person.getName());
        System.out.println("age"+person.getAge());
        System.out.println(person.toString());
        printBeanName(applicationContext);
        }

        private static void printBeanName(ApplicationContext applicationContext) {
        }
}

編寫一個Person類,並提供get,set方法
在這裏插入圖片描述

最後啓動看結果
在這裏插入圖片描述
說明bean已經註冊進IOC容器中了

下面我們來解析一下是怎麼注入進去的

點擊ClassPathXmlApplicationContext
在這裏插入圖片描述

在這裏插入圖片描述
兩個主要方法:setConfigLocations,refresh
先看setConfigLocations
在這裏插入圖片描述
在這裏插入圖片描述

下面看refresh方法,refresh主要模版在父類AbstractApplicationContext中,

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        //加鎖,保證同時只能使用一個方法
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            //創建Bean工廠
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //對beanfactory
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                //把BeanPostProcessor註冊到beanFactory的一個list中
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

再看prepareRefresh

protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);
        if (this.logger.isDebugEnabled()) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Refreshing " + this);
            } else {
                this.logger.debug("Refreshing " + this.getDisplayName());
            }
        }

        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
        } else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        this.earlyApplicationEvents = new LinkedHashSet();
    }

AbstractRefreshableApplicationContext

protected final void refreshBeanFactory() throws BeansException {
        //如果之前存在BeanFactory
        if (hasBeanFactory()) {
            //destory此BeanFactory註冊的單例bean
            destroyBeans();
            //置爲當前wrap引用指向null
            closeBeanFactory();
        }
        try {
            //new BeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            //把beanFactory和當前Context用id關聯
            beanFactory.setSerializationId(getId());
            //設置把Contxt的一些標誌設置給BeanFactory,這裏主要有兩個
            //allowBeanDefinitionOverriding(bean同名 覆蓋or exception),allowCircularReferences(bean可以循環引用)
            customizeBeanFactory(beanFactory);
            //主要方法,繼續跟
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

——————————————————————————————
首先進入getBean,因爲spring是通過getBean來加載的,然後getBean會有一系列符合的重載,但是最終都會跳轉到doGetBean。我們知道,在spring裏。一旦do什麼就會開始幹實事了。
一下是deGetBean的源碼:
比較長,請耐心看完

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    String beanName = this.transformedBeanName(name);
// 首先嚐試從緩存獲取單例bean
    Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if (sharedInstance != null && args == null) {
        if (this.logger.isDebugEnabled()) {
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 獲取給定bean的實例對象 如果是FactoryBean需要進行相關處理
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
    // 只有在單例情況下會去解決循環依賴,原型模式下,如果存在A中有B屬性,B中有A屬性,依賴注入時
    // 會產生A還沒創建完因爲對於B的創建再次返回創建A,造成循環依賴,因此對於這種情況直接拋出異常
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        BeanFactory parentBeanFactory = this.getParentBeanFactory();
    // 檢查當前BeanFactory是否存在需要創建實例的BeanDefinition 如果不存在 則委託父級容器加載
        if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            String nameToLookup = this.originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }

            if (args != null) {
                return parentBeanFactory.getBean(nameToLookup, args);
            }

            return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
        // 判斷創建的bean是否需要進行類型驗證
        if (!typeCheckOnly) {
        // 向容器標記指定的bean實例已經創建
            this.markBeanAsCreated(beanName);
        }

        try {
        // 根據指定bean名稱獲取父級BeanDefinition 解決bean繼承時子類合併父類公共屬性問題
            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
      // 獲取當前bean所有依賴bean的名稱
            String[] dependsOn = mbd.getDependsOn();
            String[] var11;
            if (dependsOn != null) {
                var11 = dependsOn;
                int var12 = dependsOn.length;

                for(int var13 = 0; var13 < var12; ++var13) {
                    String dep = var11[var13];
                    if (this.isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 爲當前bean註冊依賴bean 以便當前bean銷燬前先銷燬依賴bean
                    this.registerDependentBean(dep, beanName);

                    try {
                    // 創建依賴bean
                        this.getBean(dep);
                    } catch (NoSuchBeanDefinitionException var24) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
                    }
                }
            }

            if (mbd.isSingleton()) {
            // 單例bean 且 緩存不存在
                sharedInstance = this.getSingleton(beanName, () -> {
                    try {
                    // 創建bean
                        return this.createBean(beanName, mbd, args);
                    } catch (BeansException var5) {
                        this.destroySingleton(beanName);
                        throw var5;
                    }
                });
            // 獲取給定bean的實例對象 如果是FactoryBean需要進行相關處理
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
                var11 = null;

                Object prototypeInstance;
                try {
                // 回調beforePrototypeCreation方法 默認實現是註冊當前創建的原型對象
                    this.beforePrototypeCreation(beanName);
                // 創建bean
                    prototypeInstance = this.createBean(beanName, mbd, args);
                } finally {
                // 回調afterPrototypeCreation方法 默認實現告訴IoC容器指定Bean的原型對象不再創建
                    this.afterPrototypeCreation(beanName);
                }
                // 獲取給定bean的實例對象 如果是FactoryBean需要進行相關處理
                bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
            // 其它scope類型處理
                String scopeName = mbd.getScope();
                Scope scope = (Scope)this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }

                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        this.beforePrototypeCreation(beanName);

                        Object var4;
                        try {
                        // 創建bean
                            var4 = this.createBean(beanName, mbd, args);
                        } finally {
                            this.afterPrototypeCreation(beanName);
                        }

                        return var4;
                    });
                    bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException var23) {
                    throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
                }
            }
        } catch (BeansException var26) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var26;
        }
    }
    // 如果需要對創建的bean實例進行類型檢查
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            } else {
                return convertedBean;
            }
        } catch (TypeMismatchException var25) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
            }

            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    } else {
        return bean;
    }
}

在deGetBean方法中通過 getSingleton 方法嘗試從緩存中獲取單例 bean

@Nullable
public Object getSingleton(String beanName) {
// 參數true 代表允許提前依賴
return this.getSingleton(beanName, true);
}

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 首先從緩存獲取單例bean
Object singletonObject = this.singletonObjects.get(beanName);
// 如果緩存爲空且當前bean在創建中
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
// 從提前加載的bean集合獲取
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果緩存爲空且允許提前依賴
if (singletonObject == null && allowEarlyReference) {
// 獲取單例bean工廠
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 單例bean工廠不爲空 則創建bean實例
singletonObject = singletonFactory.getObject();
// 添加到提前加載bean緩存中
this.earlySingletonObjects.put(beanName, singletonObject);
// 將單例bean工廠移除 因爲已經調用工廠加載bean實例 無需再次調用
this.singletonFactories.remove(beanName);
}
}
}
}

return singletonObject;

}

deCreateBean的方法,創建bean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        //第一步 創建bean實例 還未進行屬性填充和各種特性的初始化
        BeanWrapper instanceWrapper = null;
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

        Object exposedObject = bean;
        try {
            // 第二步 進行屬性填充
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                // 第三步 初始化bean 執行初始化方法
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }catch (Throwable ex) {
            //  拋相應的異常
        }

        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
        return exposedObject;
    }

 AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(JobService.class);
        for (String beanname:context.getBeanDefinitionNames())
        {
            System.out.println("--------"+beanname);
        }
        System.out.println("context.getBean(JobService.class) = " + context.getBean

初始化bean,然後再來拿bean,我們點進AnnotationConfigApplicationContext來看
在這裏插入圖片描述
會調用 this()默認無參構造方法
在這裏插入圖片描述
他new了一個對象
在這裏插入圖片描述
也就是 DefaultListableBeanFactory,當然 這個就是所謂我們平常所說的 bean工廠,其父類就是 BeanFactory,BeanFactory有很多子類,DefaultListableBeanFactory就是其中一個子類。

bean的生命週期就是圍繞refresh()這個方法的

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 準備好刷新上下文.
      prepareRefresh();

      // 返回一個Factory 爲什麼需要返回一個工廠  因爲要對工廠進行初始化
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 準備bean工廠,以便在此上下文中使用。
      prepareBeanFactory(beanFactory);

      try {
         // 允許在上下文子類中對bean工廠進行後處理。 在spring5  並未對此接口進行實現
         postProcessBeanFactory(beanFactory);

         // 在spring的環境中去執行已經被註冊的 Factory processors
         //設置執行自定義的postProcessBeanFactory和spring內部自己定義的
         invokeBeanFactoryPostProcessors(beanFactory);

         // 註冊postProcessor
         registerBeanPostProcessors(beanFactory);

         // 初始化此上下文的消息源。
         initMessageSource();

         // 初始化此上下文的事件多播程序。
         initApplicationEventMulticaster();

         // 在特定上下文子類中初始化其他特殊bean。
         onRefresh();

         //檢查偵聽器bean並註冊它們。
         registerListeners();

         // 實例化所有剩餘的(非懶加載)單例。
         //new 單例對象
         finishBeanFactoryInitialization(beanFactory);

         // 最後一步:發佈相應的事件
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

finishBeanFactoryInitialization(beanFactory);這個是最重要的方法,這個方法主要是告訴我們SpringBean如何初始化的

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   **// 實例化所有單例對象
   beanFactory.preInstantiateSingletons();**
}

點進去最後的一個方法,beanFactory.preInstantiateSingletons();

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isDebugEnabled()) {
      logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   //所有bean的名字
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               final FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                              ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

我們可以看到其中有這個方法

List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

來保存bean的名字,那this.beanDefinitionNames是一個什麼東西
beanDefinition是個很重要的概念:
我們傳統的創建對象的方法就是new一個對象出來。但是交給Spring就不一樣了,會先通過SpringScan掃描類,當掃描到的時候回去自己new 一個對象,然後會把掃描到各種類的信息取出來。
但是取出來放哪兒了呢,在DefaultListableBeanFactory中有一個Map,叫做

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

會把bean的信息保存在這個map裏。循環map中的key集合。

//觸發所有非延遲加載單例beans的初始化,只要步驟調用getBean
//根據List名字從Map當中把BeanDefinition依次拿出來開始new對象
for (String beanName : beanNames) {
  //合併父BeanDefinition
  //通過Map的名字拿BeanDefinition
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    //判斷當前類是否抽象 是否爲單例  是否爲懶加載  如果條件都成立 則繼續
   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
     //判斷該類是否爲FactoryBean FactoryBean這裏不進行講解 不懂得朋友可以去了解下
     //如果不是FactoryBean
      if (isFactoryBean(beanName)) {
         Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
         if (bean instanceof FactoryBean) {
            final FactoryBean<?> factory = (FactoryBean<?>) bean;
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
               isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                           ((SmartFactoryBean<?>) factory)::isEagerInit,
                     getAccessControlContext());
            }
            else {
               isEagerInit = (factory instanceof SmartFactoryBean &&
                     ((SmartFactoryBean<?>) factory).isEagerInit());
            }
            if (isEagerInit) {
               getBean(beanName);
            }
         }
      }
      else {
        //則直接調用getBean
         getBean(beanName);
      }
   }
}

在這裏插入圖片描述
getBean的方法,然後看看doGetBean

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

  /**
  *通過name獲取beanName。這裏不使用name直接做beanName
  * name可能會以&字符開頭,表用調用者想獲取FactoryBean本身,而非FactoryBean
  *實現類所創建的bean。在BeanFactory中,FactoryBean的實現類和其他的bean存儲方式是一致的即
  * <beanName, bean> ,beanName中沒有&字符的。所以我們需要將name的首字母&移除,這樣才能取到
  *FactoryBean實例
  */
   final String beanName = transformedBeanName(name);
   Object bean;

   // Eagerly check singleton cache for manually registered singletons.
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
      if (logger.isDebugEnabled()) {
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                  "' that is not fully initialized yet - a consequence of a circular reference");
         }
         else {
            logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }

   else {
      // Fail if we're already creating this bean instance:
      // We're assumably within a circular reference.
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      // Check if bean definition exists in this factory.
      BeanFactory parentBeanFactory = getParentBeanFactory();
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         // Not found -> check parent.
         String nameToLookup = originalBeanName(name);
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            // Delegation to parent with explicit args.
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else {
            // No args -> delegate to standard getBean method.
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
      }

      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }

      try {
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         checkMergedBeanDefinition(mbd, beanName, args);

         // 一個註解叫@DependsOn:A類創建 必須B類創建出來再創建A類
         String[] dependsOn = mbd.getDependsOn();
         if (dependsOn != null) {
            for (String dep : dependsOn) {
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               registerDependentBean(dep, beanName);
               try {
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }

         // Create bean instance.
         if (mbd.isSingleton()) {
           //真正開始創建對象
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  // Explicitly remove instance from singleton cache: It might have been put there
                  // eagerly by the creation process, to allow for circular reference resolution.
                  // Also remove any beans that received a temporary reference to the bean.
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }

         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }

         else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
               throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
               Object scopedInstance = scope.get(beanName, () -> {
                  beforePrototypeCreation(beanName);
                  try {
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     afterPrototypeCreation(beanName);
                  }
               });
               bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch (IllegalStateException ex) {
               throw new BeanCreationException(beanName,
                     "Scope '" + scopeName + "' is not active for the current thread; consider " +
                     "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                     ex);
            }
         }
      }
      catch (BeansException ex) {
         cleanupAfterBeanCreationFailure(beanName);
         throw ex;
      }
   }

   // Check if required type matches the type of the actual bean instance.
   if (requiredType != null && !requiredType.isInstance(bean)) {
      try {
         T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
         if (convertedBean == null) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
         }
         return convertedBean;
      }
      catch (TypeMismatchException ex) {
         if (logger.isDebugEnabled()) {
            logger.debug("Failed to convert bean '" + name + "' to required type '" +
                  ClassUtils.getQualifiedName(requiredType) + "'", ex);
         }
         throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
      }
   }
   return (T) bean;
}

Object sharedInstance = getSingleton(beanName);重點爲這行代碼,我們點進去getSingleton(beanName)這個方法來看
在這裏插入圖片描述
正在要new一個對象的時候 他會調用getSingleton方法,那麼在這個方法中Object singletonObject = this.singletonObjects.get(beanName);

/** Cache of singleton objects: bean name --> bean instance */
//用於存放完全初始化好的bean從該緩存中取出bean可以直接使用
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

從某一種角度來說,Spring容器就是一個map,還是一個線程安全的map

然後 singletonObjects是一個單例池。

/** Cache of early singleton objects: bean name --> bean instance */
//存放原始的bean對象用於解決循環依賴,注意:存到裏面的對象還沒被填充到屬性
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

一個bean放到singletonObjects之後,把一個對象new出來之後,如果這個對象要循環引用那spring就會先把他放到earlySingletonObjects這個當中.get是因爲怕對象已經放到early當中所以先去get一遍

if (sharedInstance != null && args == null) {//如果條件成立的話

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);//直接返回調

//如果條件不成立直接else

if (isPrototypeCurrentlyInCreation(beanName)) //判斷這個類是否正在創建,什麼意思 因爲spring正在創建一類的時候他會進行標識這個類我正在創建中,然後獲取bean工廠

BeanFactory parentBeanFactory = getParentBeanFactory();//這裏不重要

接下來看這個單例的

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         if (this.singletonsCurrentlyInDestruction) {
            throw new BeanCreationNotAllowedException(beanName,
                  "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                  "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
         }
         if (logger.isDebugEnabled()) {
            logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
         }
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         catch (IllegalStateException ex) {
            // Has the singleton object implicitly appeared in the meantime ->
            // if yes, proceed with it since the exception indicates that state.
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               throw ex;
            }
         }
         catch (BeanCreationException ex) {
            if (recordSuppressedExceptions) {
               for (Exception suppressedException : this.suppressedExceptions) {
                  ex.addRelatedCause(suppressedException);
               }
            }
            throw ex;
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

Object singletonObject = this.singletonObjects.get(beanName);
第一個getSingleton:單例池拿,拿不到到緩存池拿,拿不到返回null 第二個:也是先從單例池拿 如果爲null, if (this.singletonsCurrentlyInDestruction)判斷對象有沒有開始創建,
然後點擊
beforeSingletonCreation(beanName);

protected void beforeSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }

點singletonsCurrentlyInCreation看看是什麼意思

/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation =
      Collections.newSetFromMap(new ConcurrentHashMap<>(16));

這是一個map,表示放在這個map裏,正在創建
緊接着調用createBean(beanName, mbd, args);開始創

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

   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // Make sure bean class is actually resolved at this point, and
   // clone the bean definition in case of a dynamically resolved Class
   // which cannot be stored in the shared merged bean definition.
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
點進去看看

@Nullable
protected Object  resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);點進來看

在這裏插入代碼片@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

我們返回剛剛

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

在doCreateBean裏面調用第二個後置處理器,我這裏都不再一一尋找了,直接列出來吧

第一次:InstantiationAwareBeanPostProcessor --postProcessBeforeInstantiation
第二次:SmartInstantiationAwareBeanPostProcessor—determineCandidateConstructors—由後置處理器決定返回那些構造方法
第三次:MergedBeanDefinitionPostProcessor——postProcessMergedBeanDefinition------緩存的
第四次:SmartInstantiationAwareBeanPostProcessor—getEarlyBeanReference----把對象放到Early當中--處理循環引用
第五次:InstantiationAwareBeanPostProcessor—postProcessAfterInstantiation---判斷要不要填充屬性
第六次:InstantiationAwareBeanPostProcessor—postProcessPropertyValues—處理屬性的值
第七次:BeanPostProcessor—postProcessBeforeInitialization —處理AOP
第八次:BeanPostProcessor----postProcessAfterInitialization
第九次爲銷燬
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章