例項化(執行建構函式)—>填充屬性—>初始化
spring依賴注入bean例項預設是單例的
org.springframework.beans.factory.support.abstractbeanfactory
protected
t dogetbean
(final string name,
@nullable
final class
requiredtype,
@nullable
final object[
] args,
boolean typecheckonly)
throws bean***ception
org.springframework.beans.factory.support.defaultsingletonbeanregistry//一級快取,單例bean名稱-->單例bean
private
final map
singletonobjects =
newconcurrenthashmap
<
>
(256);
//正在建立中的
private
final set
singletonscurrentlyincreation =
collections.
newsetfrommap
(new
concurrenthashmap
<
>(16
));//二級快取,這個bean還沒有完成依賴注入,bean名稱-->預載入bean
private
final map
earlysingletonobjects =
newhashmap
<
>(16
);//**快取,bean名稱-->singletonbean的生產工廠
private
final map?>> singletonfactories =
newhashmap
<
>(16
);//儲存所有已經完成例項化的bean的名字(name)
private
final set
registeredsingletons =
newlinkedhashset
(64);
public
boolean
issingletoncurrentlyincreation
(string beanname)
/**這段**發生在createbeaninstance之後,也就是說單例物件此時已經被建立出來(呼叫了構造器)。
這個物件已經被生產出來了,雖然還不完美(還沒有進行初始化的第二步和第三步),但是已經能被人認出來了(根據物件引用能定位到堆中的物件),所以spring此時將這個物件提前**出來讓大家認識,讓大家使用
*/protected
void
addsingletonfactory
(string beanname, objectfactory<
?> singletonfactory)}}
//allowearlyreference引數,true設定標識允許早期依賴
@nullable
protected object getsingleton
(string beanname,
boolean allowearlyreference)}}
}return singletonobject;
}
如果不存在迴圈依賴時,例如:bean a → bean b → bean c
spring會先建立bean c,再建立bean b(並將bean c注入到bean b中),最後再建立bean a(並將bean b注入到bean a中)。
如果我們存在迴圈依賴,spring上下文不知道應該先建立哪個bean,因為它們依賴於彼此。
spring會在載入上下文時,丟擲乙個beancurrentlyincreationexception。
使用 @lazy,對乙個bean使用延時載入。
這個bean並沒有完全的初始化完,實際上他注入的是乙個**,只有當他首次被使用的時候才會被完全的初始化。
使用 setter/field 注入
你對你須要注入的bean(scoper=「singleton」)是使用setter注入(或字段注入),而不是建構函式注入。
加入singletonfactories**快取的前提是執行了構造器,所以構造器的迴圈依賴沒法解決。
field屬性注入迴圈依賴(scoper=「prototype」)會丟擲異常。
spring是先將bean物件例項化【依賴無參建構函式】—>再設定物件屬性的。
spring先用構造器例項化bean物件----->將例項化結束的物件放到乙個map中,並且spring提供獲取這個未設定屬性的例項化物件的引用方法。
使用 @postconstruct
在要注入的屬性(該屬性是乙個bean)上使用 @autowired
並使用@postconstruct 標註在另乙個方法,且該方法裡設定對其他的依賴。
@component
public
class
circulardependencya
public circulardependencyb getcircb()
}
@component
public
class
circulardependencya
implements
, initializingbean
@override
public
void
afterpropertiesset()
throws exception
@override
public
void
(throws bean***ception
}
2 單例模式
一 簡介 什麼是單例模式?單例模式是指 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。單例模式實現一 使用類方法實現 class singleton object instance none classmethod definstance cls if cls.instance retur...
2 單例模式
單執行緒環境 public class singleton1 private static singleton1 instance null public static singleton1 getinstance 先加鎖後判斷,但是加鎖開銷大,效率不高 public class singleton...
設計模式 2 單例模式
單例模式,也是非常好理解的一種設計模式。單例,也叫單件,目的是為了保證乙個類只有乙個例項。當然,沒使用上單例模式的時候,在 實現時候,注意不要隨便new某個物件,這 的確可以,但很不安全。因此簡單 一處理,乙個單例模式便出來了。using system using system.collection...