Spring中的Bean對象初始化詳解
Bean對象初始化詳解
即使我們在不了解Spring對bean的初始化機制,我們也可以根據(jù)Java語言的特性猜測到其很有可能是通過反射機制來完成Bean的初始化操作
接下來我們一步一步的剖析Spring對Bean的初始化操作。
首先Spring會通過調(diào)用 getBean(String name)來獲取Bean,在獲取bean的過程中完成的Bean的初始化操作。
AbstractBeanFactory類中:
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
在doGetBean方法中會判斷bean的類型單例、原型,如果是單例則需要判斷是否已經(jīng)初始化bean并添加到緩存中,如果是原型bean則需要重新初始化bean,由于Spring對beanName提供了別名機制,所有需要通過beanName獲取最終的bean名稱。
@SuppressWarnings("unchecked") protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //查找name是否有別名,獲取最終的beanName final String beanName = transformedBeanName(name); Object bean; //如果bean是單例模式,首先嘗試從緩存中獲取 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是否是FactoryBean,如果不是直接返回sharedInstance,否則調(diào)用sharedInstance.getObject()方法返回bean bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //判斷容器是否有服容器,如果有則首先嘗試從父容器中獲取 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ù)beanName獲取bean的元數(shù)據(jù) final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. 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); } } // bean是單例 if (mbd.isSingleton()) { //獲取bean,首先會暴露一個ObjectFactory,通過調(diào)用getObject來調(diào)用createBean(beanName, mbd, args)獲取bean sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { // return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); //會判斷bean是否是FactoryBean,如果不是直接返回sharedInstance,否則調(diào)用sharedInstance.getObject()方法返回bean bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //bean是原型 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); //初始化bean prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //bean是其他模式 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; } } //省略代碼.......... return (T) bean; }
接下來我們看看在createBean(String beanName, RootBeanDefinition mbd, Object[] args)中進(jìn)行的處理操作,在createBean中會通過BeanDefinition中獲取類名resolvedClass(反射機制重要的一個參數(shù)),并且會調(diào)用resolveBeforeInstantiation在bean初始的過程中做一些預(yù)處理(簡單來說就是BeanPostProcessor的實現(xiàn)類所做的處理操作
AbstractAutowireCapableBeanFactory:
@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; //獲取類名,通過反射機制來實例化類 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); //設(shè)置類名 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想要在初始化后使用之前做一些預(yù)處理操作 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); } //初始化bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
doCreateBean中完成的處理操作就比較多了,簡單來說調(diào)用了幾個方法完成了bean的初始化操作:
createBeanInstance完成通過構(gòu)造函數(shù)初始化bean的操作;
addSingletonFactory完成將初始化的bean提前暴露出去,這樣就解決了單例bean非構(gòu)造函數(shù)的循環(huán)引用問題;
populateBean完成bean的屬性注入操作,通過set方法或者注解注入屬性;
initializeBean完成了bean注入時設(shè)置的init-method方法的執(zhí)行,同時在執(zhí)行init-method之前會調(diào)用applyBeanPostProcessorsBeforeInitialization完成bean使用前的處理操作,調(diào)用applyBeanPostProcessorsAfterInitialization完成bean初始化后的操作;
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //初始化bean實例 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } //將初始化的bean提前暴露出去,暴露一個ObjectFactory,這也是Spring解決單例bean非構(gòu)造函數(shù)依賴的解決方法 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"); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //初始化bean的各種注入或者setXX參數(shù) 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); } } // // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
createBeanInstance中會通過bean的構(gòu)造函數(shù)或者默認(rèn)構(gòu)造函數(shù)來完成bean的初始化工作。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { //省略代碼............. if (resolved) { if (autowireNecessary) { //通過構(gòu)造函數(shù)初始化 return autowireConstructor(beanName, mbd, null, null); } else { //使用默認(rèn)構(gòu)造函數(shù)初始化 return instantiateBean(beanName, mbd); } } // Need to determine the constructor... 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. return instantiateBean(beanName, mbd); }
instantiateBean中會調(diào)用bean初始策略InstantiationStrategy的實現(xiàn)類完成bean的初始化操作。
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { 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 { //調(diào)用bean初始化策InstantiationStrategy略初始化bean 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); } }
調(diào)用InstantiationStrategy的instantiate方法完成初始化操作。
SimpleInstantiationStrategy(InstantiationStrategy實現(xiàn)類)
@Override public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (bd.getMethodOverrides().isEmpty()) { 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); } } } //最終在BeanUtils中完成bean的初始化操作 return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(bd, beanName, owner); } }
最終我們發(fā)現(xiàn)bean的初始化操作是在BeanUtils中完成的,通過反射機制完成Bean的初始化操作。
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { ReflectionUtils.makeAccessible(ctor); //通過反射機制初始化bean return ctor.newInstance(args); } catch (InstantiationException ex) { throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); } catch (IllegalAccessException ex) { throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); } catch (IllegalArgumentException ex) { throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); } catch (InvocationTargetException ex) { throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); } }
總結(jié)
簡單來說Spring對bean的初始化操作就是根據(jù)反射機制通過構(gòu)造函數(shù)進(jìn)行初始化的。
接下來我們再用一篇介紹一下bean的屬性注入相關(guān)的操作。
到此這篇關(guān)于Spring中的Bean對象初始化詳解的文章就介紹到這了,更多相關(guān)Bean對象初始化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java并發(fā)底層實現(xiàn)原理學(xué)習(xí)心得
本片文章是學(xué)習(xí)Java并發(fā)底層實現(xiàn)原理的一篇知識心得,對大家學(xué)習(xí)這個方便的知識很有幫助,一起參考下。2018-01-01Windows10系統(tǒng)下修改jar中的文件并重新打包成jar文件然后運行的操作步驟
這篇文章主要介紹了Windows10系統(tǒng)下修改jar中的文件并重新打包成jar文件然后運行的操作步驟,文中通過圖文結(jié)合的形式給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-08-08java web response提供文件下載功能的實例講解
下面小編就為大家分享一篇java web response提供文件下載功能的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01在springboot中使用注解將值注入?yún)?shù)的操作
這篇文章主要介紹了在springboot中使用注解將值注入?yún)?shù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04