激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 淺談Spring IoC容器的依賴注入原理

淺談Spring IoC容器的依賴注入原理

2021-04-09 11:51芥末無(wú)疆sss Java教程

這篇文章主要介紹了淺談Spring IoC容器的依賴注入原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

本文介紹了淺談spring ioc容器的依賴注入原理,分享給大家,具體如下:

ioc容器初始化的過(guò)程,主要完成的工作是在ioc容器中建立 beandefinition 數(shù)據(jù)映射,并沒(méi)有看到ioc容器對(duì)bean依賴關(guān)系進(jìn)行注入,

假設(shè)當(dāng)前ioc容器已經(jīng)載入用戶定義的bean信息,依賴注入主要發(fā)生在兩個(gè)階段

正常情況下,由用戶第一次向ioc容器索要bean時(shí)觸發(fā)

但我們可以在 beandefinition 信息中通過(guò)控制 lazy-init 屬性來(lái)讓容器完成對(duì)bean的預(yù)實(shí)例化,即在初始化的過(guò)程中就完成某些bean的依賴注入的過(guò)程

1.getbean觸發(fā)的依賴注入

在基本的ioc容器接口 beanfactory 中,有一個(gè) getbean 的接口定義,這個(gè)接口的實(shí)現(xiàn)就是觸發(fā)依賴注入發(fā)生的地方.為了進(jìn)一步了解這個(gè)依賴注入的過(guò)程,我們從 defaultlistablebeanfactory 的基類 abstractbeanfactory 入手去看看getbean的實(shí)現(xiàn)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// 這里是對(duì) beanfactory 接口的實(shí)現(xiàn),比如getbean接口方法
  //這些getbean接口方法最終是通過(guò)調(diào)用dogetbean來(lái)實(shí)現(xiàn)的
  @override
  public object getbean(string name) throws beansexception {
    return dogetbean(name, null, null, false);
  }
 
  @override
  public <t> t getbean(string name, class<t> requiredtype) throws beansexception {
    return dogetbean(name, requiredtype, null, false);
  }
 
  @override
  public object getbean(string name, object... args) throws beansexception {
    return dogetbean(name, null, args, false);
  }
 
  public <t> t getbean(string name, class<t> requiredtype, object... args) throws beansexception {
    return dogetbean(name, requiredtype, args, false);
  }
 
    //這里是實(shí)際取得bean的地方,也就是觸發(fā)依賴注入發(fā)生的地方
  @suppresswarnings("unchecked")
  protected <t> t dogetbean(
      final string name, final class<t> requiredtype, final object[] args, boolean typecheckonly)
      throws beansexception {
 
    final string beanname = transformedbeanname(name);
    object bean;
 
    // eagerly check singleton cache for manually registered singletons.
        //急切地檢查單例人士緩存手動(dòng)注冊(cè)的單例
        //先從緩存中取得bean,處理那些已經(jīng)被創(chuàng)建過(guò)的單例bean,這種bean不要重復(fù)創(chuàng)建
    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 + "'");
        }
      }
            //這里的getobjectforbeaninstance完成的是factorybean的相關(guān)處理,以取得factorybean的相關(guān)處理,以取得factorybean的生產(chǎn)結(jié)果,beanfactory和factorybean的區(qū)別已在前面講過(guò),這個(gè)過(guò)程在后面還會(huì)詳細(xì)地分析
      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);
      }
 
            // // 檢查ioc容器中的beandefinition是否存在,若在當(dāng)前工廠不存在則去順著雙親beanfactory鏈一直向上找
      beanfactory parentbeanfactory = getparentbeanfactory();
      if (parentbeanfactory != null && !containsbeandefinition(beanname)) {
        // not found -> check parent.
        string nametolookup = originalbeanname(name);
        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 {
                //根據(jù)bean的名字取得beandefinition
        final rootbeandefinition mbd = getmergedlocalbeandefinition(beanname);
        checkmergedbeandefinition(mbd, beanname, args);
 
        // guarantee initialization of beans that the current bean depends on.
                //遞歸獲得當(dāng)前bean依賴的所有bean(如果有的話)
        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);
            getbean(dep);
          }
        }
 
                //通過(guò)調(diào)用createbean方法創(chuàng)建singleton bean實(shí)例
        if (mbd.issingleton()) {
          sharedinstance = getsingleton(beanname, new objectfactory<object>() {
            @override
            public object getobject() throws beansexception {
              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);
        }
                //這里是創(chuàng)建prototype bean的地方
        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, new objectfactory<object>() {
              @override
              public object getobject() throws beansexception {
                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.
        // 這里對(duì)創(chuàng)建的bean進(jìn)行類型檢查,如果沒(méi)有問(wèn)題,就返回這個(gè)新創(chuàng)建的bean,這個(gè)bean已經(jīng)是包含了依賴關(guān)系的bean
    if (requiredtype != null && bean != null && !requiredtype.isassignablefrom(bean.getclass())) {
      try {
        return gettypeconverter().convertifnecessary(bean, requiredtype);
      }
      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;
  }

依賴注入就是在這里被觸發(fā)的.而依賴注入的發(fā)生是在容器中的beandefinition數(shù)據(jù)已經(jīng)建立好的前提下進(jìn)行的.雖然我們可以用最簡(jiǎn)單的方式來(lái)描述ioc容器,那就是視其為一個(gè)hashmap,但只能說(shuō)這個(gè)hashmap是容器的最基本的數(shù)據(jù)結(jié)構(gòu),而不是ioc容器的全部.

關(guān)于這個(gè)依賴注入過(guò)程會(huì)在下面詳解,圖1.1可以看到依賴注入的大致過(guò)程.

淺談Spring IoC容器的依賴注入原理

圖1.1 依賴注入的過(guò)程

getbean是依賴注入的起點(diǎn),之后會(huì)調(diào)用abstractautowirecapablebeanfactory中的createbean來(lái)生產(chǎn)需要的bean,還對(duì)bean初始化進(jìn)行了處理,比如實(shí)現(xiàn)了在beandefinition中的init-method屬性定義,bean后置處理器等.下面通過(guò)createbean代碼了解這個(gè)過(guò)程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
@override
  protected object createbean(string beanname, rootbeandefinition mbd, 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.
        //這里判斷需要?jiǎng)?chuàng)建的bean是否可以被實(shí)例化,這個(gè)類是否可以通過(guò)類加載器來(lái)載入
    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.
            //如果bean配置了postprocessor,那么這里返回的是一個(gè)proxy
      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 ex) {
      // a previously detected exception with proper bean creation context already...
      throw ex;
    }
    catch (implicitlyappearedsingletonexception ex) {
      // an illegalstateexception to be communicated up to defaultsingletonbeanregistry...
      throw ex;
    }
    catch (throwable ex) {
      throw new beancreationexception(
          mbdtouse.getresourcedescription(), beanname, "unexpected exception during bean creation", ex);
    }
  }
 
 
 
  //接著到docreate中去看看bean是怎樣生成的
  protected object docreatebean(final string beanname, final rootbeandefinition mbd, final object[] args) {
    // instantiate the bean.
        //用來(lái)持有創(chuàng)建出來(lái)的bean對(duì)象
    beanwrapper instancewrapper = null;
        //如果是單例,則先把緩存中的同名bean清除
    if (mbd.issingleton()) {
      instancewrapper = this.factorybeaninstancecache.remove(beanname);
    }
        //這里是創(chuàng)建bean的地方,由createbeaninstance來(lái)完成
    if (instancewrapper == null) {
            //根據(jù)指定bean使用對(duì)應(yīng)的策略創(chuàng)建新的實(shí)例,如:工廠方法,構(gòu)造函數(shù)自動(dòng)注入,簡(jiǎn)單初始化
      instancewrapper = createbeaninstance(beanname, mbd, args);
    }
    final object bean = (instancewrapper != null ? instancewrapper.getwrappedinstance() : null);
    class<?> beantype = (instancewrapper != null ? instancewrapper.getwrappedclass() : null);
 
    // allow post-processors to modify the merged bean definition.
    synchronized (mbd.postprocessinglock) {
      if (!mbd.postprocessed) {
        applymergedbeandefinitionpostprocessors(mbd, beantype, beanname);
        mbd.postprocessed = true;
      }
    }
 
    // eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like beanfactoryaware.
        //是否需要提前曝光:單例&允許循環(huán)依賴&當(dāng)前bean正在創(chuàng)建中,檢測(cè)循環(huán)依賴
    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");
      }
            //為避免后期循環(huán)依賴,可以在bean初始化完成前將創(chuàng)建實(shí)例的objectfactory加入工廠
      addsingletonfactory(beanname, new objectfactory<object>() {
        @override
        public object getobject() throws beansexception {
                    //對(duì)bean再次依賴引用,主要應(yīng)用smartinstantialiationaware beanpostprocessor,
                    //其中我們熟知的aop就是在這里將advice動(dòng)態(tài)織入bean中,若無(wú)則直接返回bean,不做任何處理
          return getearlybeanreference(beanname, mbd, bean);
        }
      });
    }
 
    // initialize the bean instance.
        //這里是對(duì)bean的初始化,依賴注入往往在這里發(fā)生,這個(gè)exposedobject在初始化處理完后悔返回作為依賴注入完成后的bean
    object exposedobject = bean;
    try {
            //對(duì)bean進(jìn)行填充,將各個(gè)屬性值注入,其中可能存在依賴于其他bean的屬性,則會(huì)遞歸初始化依賴bean
      populatebean(beanname, mbd, instancewrapper);
      if (exposedobject != null) {
                //調(diào)用初始化方法,比如init-method
        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);
      }
    }
 
    if (earlysingletonexposure) {
      object earlysingletonreference = getsingleton(beanname, false);
            // earlysingletonreference 只有在檢測(cè)到有循環(huán)依賴的情況下才會(huì)非空
      if (earlysingletonreference != null) {
        if (exposedobject == bean) {
                    //如果exposedobject 沒(méi)有在初始化方法中被改變,也就是沒(méi)有被增強(qiáng)
          exposedobject = earlysingletonreference;
        }
        else if (!this.allowrawinjectiondespitewrapping && hasdependentbean(beanname)) {
          string[] dependentbeans = getdependentbeans(beanname);
          set<string> actualdependentbeans = new linkedhashset<string>(dependentbeans.length);
          for (string dependentbean : dependentbeans) {
                        //檢測(cè)依賴
            if (!removesingletonifcreatedfortypecheckonly(dependentbean)) {
              actualdependentbeans.add(dependentbean);
            }
          }
                    //因?yàn)閎ean創(chuàng)建后其所依賴的bean一定是已經(jīng)創(chuàng)建的,actualdependentbeans非空則表示當(dāng)前bean創(chuàng)建后其依賴的bean卻沒(méi)有全部創(chuàng)建完,也就是說(shuō)存在循環(huán)依賴
          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.");
          }
        }
      }
    }
      // register bean as disposable.
    try {
            //根據(jù)scope注冊(cè)bean
      registerdisposablebeanifnecessary(beanname, bean, mbd);
    }
    catch (beandefinitionvalidationexception ex) {
      throw new beancreationexception(mbd.getresourcedescription(), beanname, "invalid destruction signature", ex);
    }
 
    return exposedobject;
  }

依賴注入其實(shí)包括兩個(gè)主要過(guò)程

  1. 生產(chǎn)bea所包含的java對(duì)象
  2. bean對(duì)象生成之后,把這些bean對(duì)象的依賴關(guān)系設(shè)置好

我們從上可以看到與依賴注入關(guān)系特別密切的方法有

createbeaninstance
生成bean包含的java對(duì)象

populatebean.
處理對(duì)各種bean對(duì)象的屬性進(jìn)行處理的過(guò)程(即依賴關(guān)系處理的過(guò)程)

先來(lái)看 createbeaninstance源碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
   * create a new instance for the specified bean, using an appropriate instantiation strategy:
   * factory method, constructor autowiring, or simple instantiation.
   * @param beanname the name of the bean
   * @param mbd the bean definition for the bean
   * @param args explicit arguments to use for constructor or factory method invocation
   * @return a beanwrapper for the new instance
   */
  protected beanwrapper createbeaninstance(string beanname, rootbeandefinition mbd, object[] args) {
    // make sure bean class is actually resolved at this point.
        // 確認(rèn)需要?jiǎng)?chuàng)建的bean實(shí)例的類可以實(shí)例化
    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);
    }
        //若工廠方法非空,則使用工廠方法策略對(duì)bean進(jìn)行實(shí)例化
    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) {
                //一個(gè)類有多個(gè)構(gòu)造函數(shù),每個(gè)構(gòu)造函數(shù)都有不同的參數(shù),所以調(diào)用前需要先根據(jù)參數(shù)鎖定構(gòu)造函數(shù)或?qū)?yīng)的工廠方法
        if (mbd.resolvedconstructororfactorymethod != null) {
          resolved = true;
          autowirenecessary = mbd.constructorargumentsresolved;
        }
      }
    }
        //如果已經(jīng)解析過(guò)則使用解析好的構(gòu)造函數(shù)方法不需要再次鎖定
    if (resolved) {
      if (autowirenecessary) {
                //構(gòu)造函數(shù)自動(dòng)注入
        return autowireconstructor(beanname, mbd, null, null);
      }
      else {
                //使用默認(rèn)構(gòu)造函數(shù)構(gòu)造
        return instantiatebean(beanname, mbd);
      }
    }
 
    // need to determine the constructor...
         // 使用構(gòu)造函數(shù)對(duì)bean進(jìn)行實(shí)例化
    constructor<?>[] ctors = determineconstructorsfrombeanpostprocessors(beanclass, beanname);
    if (ctors != null ||
        mbd.getresolvedautowiremode() == rootbeandefinition.autowire_constructor ||
        mbd.hasconstructorargumentvalues() || !objectutils.isempty(args)) {
      return autowireconstructor(beanname, mbd, ctors, args);
    }
 
    // no special handling: simply use no-arg constructor.
        //使用默認(rèn)的構(gòu)造函數(shù)對(duì)bean進(jìn)行實(shí)例化
    return instantiatebean(beanname, mbd);
  }
 
  /**
   * instantiate the given bean using its default constructor.
   * @param beanname the name of the bean
   * @param mbd the bean definition for the bean
   * @return a beanwrapper for the new instance
   */
    //最常見(jiàn)的實(shí)例化過(guò)程instantiatebean
  protected beanwrapper instantiatebean(final string beanname, final rootbeandefinition mbd) {
         //使用默認(rèn)的實(shí)例化策略對(duì)bean進(jìn)行實(shí)例化,默認(rèn)的實(shí)例化策略是
    //cglibsubclassinginstantiationstrategy,也就是使用cglib實(shí)例化bean
    try {
      object beaninstance;
      final beanfactory parent = this;
      if (system.getsecuritymanager() != null) {
        beaninstance = accesscontroller.doprivileged(new privilegedaction<object>() {
          @override
          public object run() {
            return getinstantiationstrategy().instantiate(mbd, beanname, parent);
          }
        }, getaccesscontrolcontext());
      }
      else {
        beaninstance = getinstantiationstrategy().instantiate(mbd, beanname, parent);
      }
      beanwrapper bw = new beanwrapperimpl(beaninstance);
      initbeanwrapper(bw);
      return bw;
    }
    catch (throwable ex) {
      throw new beancreationexception(
          mbd.getresourcedescription(), beanname, "instantiation of bean failed", ex);
    }
  }

這里使用了cglib對(duì)bean進(jìn)行實(shí)例化.cglib是一個(gè)字節(jié)碼生成器的類庫(kù),它提供了一系列的api來(lái)提供生成和轉(zhuǎn)換java的字節(jié)碼的功能.

在spring aop中也使用cglib對(duì)java的字節(jié)碼進(jìn)行增強(qiáng).在ioc容器中,要了解怎樣使用cglib來(lái)生成bean對(duì)象,需要看一下simpleinstantiationstrategy類.它是spring用來(lái)生成bean對(duì)象的默認(rèn)類,它提供了兩種實(shí)例化bean對(duì)象的方法

  1. 通過(guò)beanutils,使用了java的反射功能
  2. 通過(guò)cglib來(lái)生成
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class simpleinstantiationstrategy implements instantiationstrategy {
@override
  public object instantiate(rootbeandefinition bd, string beanname, beanfactory owner) {
    // don't override the class with cglib if no overrides.
    if (bd.getmethodoverrides().isempty()) {
            //這里取得指定的構(gòu)造器或者生成對(duì)象的工廠方法來(lái)對(duì)bean進(jìn)行實(shí)例化
      constructor<?> constructortouse;
      synchronized (bd.constructorargumentlock) {
        constructortouse = (constructor<?>) bd.resolvedconstructororfactorymethod;
        if (constructortouse == null) {
          final class<?> clazz = bd.getbeanclass();
          if (clazz.isinterface()) {
            throw new beaninstantiationexception(clazz, "specified class is an interface");
          }
          try {
            if (system.getsecuritymanager() != null) {
              constructortouse = accesscontroller.doprivileged(new privilegedexceptionaction<constructor<?>>() {
                @override
                public constructor<?> run() throws exception {
                  return clazz.getdeclaredconstructor((class[]) null);
                }
              });
            }
            else {
              constructortouse = clazz.getdeclaredconstructor((class[]) null);
            }
            bd.resolvedconstructororfactorymethod = constructortouse;
          }
          catch (throwable ex) {
            throw new beaninstantiationexception(clazz, "no default constructor found", ex);
          }
        }
      }
      //通過(guò)beanutils進(jìn)行實(shí)例化,這個(gè)beanutils的實(shí)例化通過(guò)constructor來(lái)實(shí)例化bean,在beanutils中可以看到具體的調(diào)用ctor.newinstance(args)
      return beanutils.instantiateclass(constructortouse);
    }
    else {  
      // 使用cglib來(lái)實(shí)例化對(duì)象
      return instantiatewithmethodinjection(bd, beanname, owner);
    }
  }
}

bean之間依賴關(guān)系的處理

依賴關(guān)系處理的入口是前面提到的populatebean方法.由于其中涉及的面太多,在這里就不貼代碼了.簡(jiǎn)要介紹一下依賴關(guān)系處理的流程:在populatebean方法中,

首先取得在beandefinition中設(shè)置的property值,然后開(kāi)始依賴注入的過(guò)程。

首先處理autowire的注入,可以byname或者是bytype,之后對(duì)屬性進(jìn)行注入。

接著需要對(duì)bean reference進(jìn)行解析,在對(duì)managelist、manageset、managemap等進(jìn)行解析完之后,就已經(jīng)為依賴注入準(zhǔn)備好了條件,這是真正把bean對(duì)象設(shè)置到它所依賴的另一個(gè)bean屬性中去的地方,其中處理的屬性是各種各樣的。

依賴注入發(fā)生在beanwrapper的setpropertyvalues中,具體的完成卻是在beanwrapper的子類beanwrapperimpl中實(shí)現(xiàn)的,它會(huì)完成bean的屬性值的注入,其中包括對(duì)array的注入、對(duì)list等集合類以及對(duì)非集合類的域進(jìn)行注入。

進(jìn)過(guò)一系列的注入,這樣就完成了對(duì)各種bean屬性的依賴注入過(guò)程。

在bean的創(chuàng)建和對(duì)象依賴注入的過(guò)程中,需要依據(jù)beandefinition中的信息來(lái)遞歸地完成依賴注入。

從前面的幾個(gè)遞歸過(guò)程中可以看到,這些遞歸都是以getbean為入口的。

一個(gè)遞歸是在上下文體系中查找需要的bean和創(chuàng)建bean的遞歸調(diào)用;

另一個(gè)遞歸是在依賴注入時(shí),通過(guò)遞歸調(diào)用容器的getbean方法,得到當(dāng)前bean的依賴bean,同時(shí)也觸發(fā)對(duì)依賴bean的創(chuàng)建和注入。

在對(duì)bean的屬性進(jìn)行依賴注入時(shí),解析的過(guò)程也是一個(gè)遞歸的過(guò)程。這樣,根據(jù)依賴關(guān)系,一層層地完成bean的創(chuàng)建和注入,直到最后完成當(dāng)前bean的創(chuàng)建。有了這個(gè)頂層bean的創(chuàng)建和對(duì)它屬性依賴注入的完成,意味著和當(dāng)前bean相關(guān)的整個(gè)依賴鏈的注入液完成了。

在bean創(chuàng)建和依賴注入完成以后,在ioc容器中建立起一系列依靠依賴關(guān)系聯(lián)系起來(lái)的bean,這個(gè)bean已經(jīng)不再是簡(jiǎn)單的java對(duì)象了。該bean系列以及bean之間的依賴關(guān)系建立完成之后,通過(guò)ioc的相關(guān)接口方法,就可以非常方便地供上層應(yīng)用使用了。

2. lazy-init屬性和預(yù)實(shí)例化

在前面的refresh方法中,我們可以看到調(diào)用了finishbeanfactoryinitialization來(lái)對(duì)配置了lazy-init的bean進(jìn)行處理。

其實(shí)在這個(gè)方法中,封裝了對(duì)lazy-init屬性的處理,實(shí)際的處理是在defaultlistablebeanfactory這個(gè)基本容器的preinstantiatesingleton方法中完成的。該方法對(duì)單例bean完成預(yù)實(shí)例化,這個(gè)預(yù)實(shí)例化的完成巧妙地委托給容器來(lái)實(shí)現(xiàn)。如果需要預(yù)實(shí)例化,那么就直接在這里采用getbean去觸發(fā)依賴注入,與正常依賴注入的觸發(fā)相比,只有觸發(fā)的時(shí)間和場(chǎng)合不同。在這里,依賴注入發(fā)生在容器執(zhí)行refresh的過(guò)程中,即ioc容器初始化的過(guò)程中,而不像一般的依賴注入一樣發(fā)生在ioc容器初始化完成以后,第一次通過(guò)getbean想容器索要bean的時(shí)候。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.jianshu.com/p/08c8c7953289

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品视频一区二区三区 | 国产精品久久久久一区二区 | 久久欧美亚洲另类专区91大神 | 一级黄色毛片播放 | 国产一级片91 | 免费观看一级黄色片 | 成年人视频在线免费观看 | 国产中文99视频在线观看 | 国产精品一区二av18款 | 亚洲欧美日韩精品久久 | xx53xx| 特黄一区二区三区 | 毛片免费试看 | 天天草天天干天天射 | 日韩视频在线不卡 | 国产精品99久久99久久久二 | 久久精品视频7 | 国产手机国产手机在线 | www日韩在线 | 特黄一级小说 | japanese hot milf free av| 久久3p视频 | 亚洲精品aa| 久久毛片免费观看 | 成人爽a毛片免费啪啪红桃视频 | 91丨九色丨国产在线观看 | 久久久综合久久久 | 国内精品久久久久久2021浪潮 | 羞羞色网站 | 国产精品久久久久久久久久久天堂 | 九九热在线免费观看视频 | 国产欧美日韩一区二区三区四区 | 欧美一区黄色 | 极品一级片| 国产成人精品区 | 久草视频在线资源 | xxxx8| 日韩黄站 | 强伦女教师视频 | 日韩中字在线 | 黄色一级片在线免费观看 |