上節講到aop,
繼續介紹bean的實例化過程,默認spring得bean是單例singleton
scope屬性可以理解成bean的生命週期
1、默認的值是singleton(単例),spring容器只會創建一個相應的bean實例,所有的對該bean的請求,spring容器都只返回這個實例。
2、還可取值proptotype(原型) ,每次請求都會獲得新的bean實例。
3、還可取值request、session、global session等(不常用)
finishBeanFactoryInitialization(beanFactory);
此方法:
................
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.實例化所有單例對象
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons()://根據beannames,調用getbean逐個實例化
這裏以下爲例
@Component("lmqsecond")
public class LmqDao23 {
public void updatesecondquery()
{
System.out.println("updateqseonduery .............");
}
}
進入
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.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.
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);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
由於lmqsecond不是懶加載,也不是factorybean,會直接進getbean()
然後進入
doGetBean
:
如上所示:
Object sharedInstance = getSingleton(beanName);//對於普通類的bean由於初始化還沒實例,這裏肯定返回null, 但對於lazy加載的bean,由於終究是getbean()才實例化,有可能是之前被其他調用實例化,對於懶加載的再次調用就不返回null了,
getSingleton就是從如下map獲得:Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
..........................
繼續docreate流程:
.............................
if (!typeCheckOnly) {
markBeanAsCreated(beanName); //把此beanname放到爲已創建集合
}
.....................
繼續實例化,如下,若有依賴,會率先實例化依賴,如下
記着無論是獲取bean實例還是初始新建bean實例,都是getbean()
繼續
// 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);
}
看上面的 getSingleton()(一個是截圖劃紅線,另一個是加粗黑體),由於createbean有兩次getSingleton(),第一次只是檢查是有已經或者正在創建(因爲singletonCurrentlyInCreation不包含,還沒到創建的地步,直接返回null),
第二次getSingleton調用是爲了真正的創建(spring已經驗證了bean創建的前期工作,若爲空,則創建),下面的是第二次的getSingleton()
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
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);//將beannname添加到singletonCurrentlyInCreation這樣一個set,表示beanname對應的bean正在創建中,
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;
}
}
看下 singletonObject = singletonFactory.getObject();
進去getObject(),由於是lamda表達式,回到表達式的createBean()
進入createBean();
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); //這裏是在bean初始化之前應用後置處理器(不是aop的後置處理器啊,參考之前的aop源碼分析),由於此時還沒產生bean實例,
(實現InstantiationAwareBeanPostProcessor,可以返回裸對象(沒有屬性,沒有依賴的裸對象))
if (bean != null) { //所以這些很不常用,因爲假設bean!=null,後面就返回了,沒有屬性自動裝配就返回bean實例,這種很少用,由於默認InstantiationAwareBeanPostProcessor實現是return 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);
}
}
繼續走,docreatebean()//真正創建bean
進去
細看下
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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); } if (mbd.getFactoryMethodName() != null) { //spring的factorymethod配置一般是基於xml的bean配置, //類似<bean id='' class='' factory-method='returnNewLmq'>,其中class有個return new lmqserv(); //同樣的包含@bean static方法也會被設置爲factorymethod,參考之前講的 appconfig, return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... 構建bean的快捷方式,方便以後構建bean的原型對象(當被實例化多次,就標記爲true,用於原型對象構建) 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); } } // Need to determine the constructor...,由後置處理器決定返回哪些構造方法,因爲實例化需要有構造方法, //默認構造函數,spring內部處理認爲沒有構造函數,帶參數除外,比如帶參 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); //
這裏提一下,rootBeanDefinition.AUTOWIRE_CONSTRUCTOR
spring的自動裝配模式不等於自動裝配技術默認爲no類型,而no是採用bytype來實現的,通過類型裝配不等於bytype(用於set方法)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.這裏是無參構造參數
return instantiateBean(beanName, mbd);
}
這裏先是無參構造,繼續看下instantiateBean(beanName, mbd);
* @return a BeanWrapper for the new instance
*/
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);//根據反射得到實例化對象
//如圖示,constructorTouse表示實例化要用到的構造函數 ,
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
返回就得到了bean實例
然後new了beanwrapper
返回
接着返回
繼續返回
至此無參構造函數的bean實例完成