<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Bean 的實(shí)例化過(guò)程源碼解析

          共 10479字,需瀏覽 21分鐘

           ·

          2021-03-26 07:24

          公眾號(hào)關(guān)注 “GitHub今日熱榜
          設(shè)為 “星標(biāo)”,帶你挖掘更多開(kāi)發(fā)神器!





          引言


          1 工程概述



          1.1 pom


          <properties>
                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                  <maven.compiler.source>1.8</maven.compiler.source>
                  <maven.compiler.target>1.8</maven.compiler.target>
                  <spring.version>5.2.8.RELEASE</spring.version>
              </properties>

              <dependencies>
                  <dependency>
                      <groupId>junit</groupId>
                      <artifactId>junit</artifactId>
                      <version>4.13</version>
                  </dependency>
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-context</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
                  <dependency>
                      <groupId>org.projectlombok</groupId>
                      <artifactId>lombok</artifactId>
                      <version>1.16.20</version>
                  </dependency>
                  <!-- 日志相關(guān)依賴 -->
                  <dependency>
                      <groupId>org.slf4j</groupId>
                      <artifactId>slf4j-api</artifactId>
                      <version>1.7.10</version>
                  </dependency>
                  <dependency>
                      <groupId>ch.qos.logback</groupId>
                      <artifactId>logback-classic</artifactId>
                      <version>1.1.2</version>
                  </dependency>
                  <dependency>
                      <groupId>ch.qos.logback</groupId>
                      <artifactId>logback-core</artifactId>
                      <version>1.1.2</version>
                  </dependency>
              </dependencies>


          1.2 bean


          @Data
          @Component
          public class CqCityBean {

              private static final String NAME = "重慶";

              public String getCityName(){

                  return NAME;
              }

          }

          @Data
          public class StudentBean {

              public final String name = "rosh";

              public final Integer age = 18;

              public StudentBean(){

                  System.out.println("invoke StudentBean NoArgsConstructor");

              }

          }
           
           
          @Data
          @Component
          public class XaCityBean {

              private static final String NAME = "西安";

              public String getCityName(){

                  return NAME;
              }

          }


          1.3 service


          @Service
          public class CityService {

              @Autowired
              public CityService(CqCityBean cq, XaCityBean xa) {
                  System.out.println(cq.getCityName());
                  System.out.println(xa.getCityName());
              }

          }


          1.4 applicationContext.xml


          <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
              http://www.springframework.org/schema/context/spring-context.xsd"
                 default-lazy-init="false">

              <context:component-scan base-package="com.rosh.service,com.rosh.bean"/>

              <bean id="student" class="com.rosh.bean.StudentBean"/>

          </beans>


          1.5 RoshTest


          public class RoshTest {

              @Test
              public void mainTest(){
                  ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
                  applicationContext.close();

              }

          }


          1.6 運(yùn)行結(jié)果



          2 主流程源碼Debug









          主流程時(shí)序圖:



          3 createBeanInstance 源碼解析


          描述:該方法主要作用bean的構(gòu)造方法創(chuàng)建對(duì)象


          protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
              // Make sure bean class is actually resolved at this point.
              Class<?> beanClass = resolveBeanClass(mbd, beanName);

              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<?> instanceSupplier = mbd.getInstanceSupplier();
              if (instanceSupplier != null) {
                return obtainFromSupplier(instanceSupplier, beanName);
              }

              //如果有FactoryMethodName屬性
              if (mbd.getFactoryMethodName() != null) {
                return instantiateUsingFactoryMethod(beanName, mbd, args);
              }

              // Shortcut when re-creating the same bean...
              boolean resolved = false;
              boolean autowireNecessary = false;
              if (args == null) {
                synchronized (mbd.constructorArgumentLock) {
                  if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                  }
                }
              }
              if (resolved) {
                if (autowireNecessary) {
                  return autowireConstructor(beanName, mbd, null, null);
                }
                else {
                  return instantiateBean(beanName, mbd);
                }
              }

              // Candidate constructors for autowiring?

              /**
               * 【1】實(shí)例化Bean帶有@Autowired注解的構(gòu)造函數(shù)
               *
               * (1) 找到帶有@Autowired注解的有參構(gòu)造函數(shù)
               * (2) 使用構(gòu)造函數(shù)創(chuàng)建對(duì)象
               */

              Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
              if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                  mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
                return autowireConstructor(beanName, mbd, ctors, args);
              }

              // Preferred constructors for default construction?
              ctors = mbd.getPreferredConstructors();
              if (ctors != null) {
                return autowireConstructor(beanName, mbd, ctors, null);
              }

              // 調(diào)用無(wú)參構(gòu)造方法創(chuàng)建bean
              return instantiateBean(beanName, mbd);
            }


          3.1 創(chuàng)建無(wú)參bean對(duì)象







          描述:使用反射調(diào)用無(wú)參構(gòu)造函數(shù)創(chuàng)建對(duì)象




          3.2 @Autowired構(gòu)造創(chuàng)建有參對(duì)象




          3.2.1 AutowiredAnnotationBeanPostProcessor


          determineCandidateConstructors 方法分析,獲取@Autowired 有參構(gòu)造函數(shù)








          3.2.2 ConstructorResolver


          ConstructorResolver類autowireConstructor方法創(chuàng)建對(duì)象







          描述:創(chuàng)建參數(shù)












          3.3 無(wú)@Autowired 構(gòu)造創(chuàng)建有參對(duì)象




          3.3.1 Debug



          AutowiredAnnotationBeanPostProcessor 檢查:





          原文鏈接:https://blog.csdn.net/qq_34125999/article/details/114858004








          關(guān)注GitHub今日熱榜,專注挖掘好用的開(kāi)發(fā)工具,致力于分享優(yōu)質(zhì)高效的工具、資源、插件等,助力開(kāi)發(fā)者成長(zhǎng)!







          點(diǎn)個(gè)在看 你最好看


          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚欧无码| 日本免费A∨ | 日本精品无码a 6 2v在线 | 国产精品黄色片 | 北条麻妃精品 |