AbstractBeanFactory 的getBean()方法调用FactoryBean
生活随笔
收集整理的這篇文章主要介紹了
AbstractBeanFactory 的getBean()方法调用FactoryBean
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在前面我們分析Spring IOC 容器實例化Bean 并進行依賴注入過程的源碼時,提到在getBean()方法觸發容器實例化Bean 的時候會調用AbstractBeanFactory 的doGetBean()方法來進行實例化的過程,源碼如下:
//真正實現向IOC容器獲取Bean的功能,也是觸發依賴注入功能的地方 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {//根據指定的名稱獲取被管理Bean的名稱,剝離指定名稱中對容器的相關依賴//如果指定的是別名,將別名轉換為規范的Bean名稱final String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons.//先從緩存中取是否已經有被創建過的單態類型的Bean//對于單例模式的Bean整個IOC容器中只創建一次,不需要重復創建Object sharedInstance = getSingleton(beanName);//IOC容器創建單例模式Bean實例對象if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {//如果指定名稱的Bean在容器中已有單例模式的Bean被創建//直接返回已經創建的Beanif (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的相關處理//注意:BeanFactory是管理容器中Bean的工廠,而FactoryBean是//創建創建對象的工廠Bean,兩者之間有區別bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.//緩存沒有正在創建的單例模式Bean//緩存中已經有已經創建的原型模式Bean//但是由于循環引用的問題導致實例化對象失敗if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.//對IOC容器中是否存在指定名稱的BeanDefinition進行檢查,首先檢查是否//能在當前的BeanFactory中獲取的所需要的Bean,如果不能則委托當前容器//的父級容器去查找,如果還是找不到則沿著容器的繼承體系向父級容器查找BeanFactory parentBeanFactory = getParentBeanFactory();//當前容器的父級容器存在,且當前容器中不存在指定名稱的Beanif (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.//解析指定Bean名稱的原始名稱String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else 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);}}//創建的Bean是否需要進行類型驗證,一般不需要if (!typeCheckOnly) {//向容器標記指定的Bean已經被創建markBeanAsCreated(beanName);}try {//根據指定Bean名稱獲取其父級的Bean定義//主要解決Bean繼承時子類合并父類公共屬性問題final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.//獲取當前Bean所有依賴Bean的名稱String[] dependsOn = mbd.getDependsOn();//如果當前Bean有依賴Beanif (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}//遞歸調用getBean方法,獲取當前Bean的依賴BeanregisterDependentBean(dep, beanName);//把被依賴Bean注冊給當前依賴的BeangetBean(dep);}}// Create bean instance.//創建單例模式Bean的實例對象if (mbd.isSingleton()) {//這里使用了一個匿名內部類,創建Bean實例對象,并且注冊給所依賴的對象sharedInstance = getSingleton(beanName, () -> {try {//創建一個指定Bean實例對象,如果有父級繼承,則合并子類和父類的定義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.//顯式地從容器單例模式Bean緩存中清除實例對象destroySingleton(beanName);throw ex;}});//獲取給定Bean的實例對象bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}//IOC容器創建原型模式Bean實例對象else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.//原型模式(Prototype)是每次都會創建一個新的對象Object prototypeInstance = null;try {//回調beforePrototypeCreation方法,默認的功能是注冊當前創建的原型對象beforePrototypeCreation(beanName);//創建指定Bean對象實例prototypeInstance = createBean(beanName, mbd, args);}finally {//回調afterPrototypeCreation方法,默認的功能告訴IOC容器指定Bean的原型對象不再創建afterPrototypeCreation(beanName);}//獲取給定Bean的實例對象bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}//要創建的Bean既不是單例模式,也不是原型模式,則根據Bean定義資源中//配置的生命周期范圍,選擇實例化Bean的合適方法,這種在Web應用程序中//比較常用,如:request、session、application等生命周期else {String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);//Bean定義資源中沒有配置生命周期范圍,則Bean定義不合法if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {//這里又使用了一個匿名內部類,獲取一個指定生命周期范圍的實例Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});//獲取給定Bean的實例對象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.//對創建的Bean實例對象進行類型檢查if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return convertedBean;}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; } //獲取給定Bean的實例對象,主要是完成FactoryBean的相關處理 protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// Don't let calling code try to dereference the factory if the bean isn't a factory.//容器已經得到了Bean實例對象,這個實例對象可能是一個普通的Bean,//也可能是一個工廠Bean,如果是一個工廠Bean,則使用它創建一個Bean實例對象,//如果調用本身就想獲得一個容器的引用,則指定返回這個工廠Bean實例對象//如果指定的名稱是容器的解引用(dereference,即是對象本身而非內存地址),//且Bean實例也不是創建Bean實例對象的工廠Beanif (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());}// Now we have the bean instance, which may be a normal bean or a FactoryBean.// If it's a FactoryBean, we use it to create a bean instance, unless the// caller actually wants a reference to the factory.//如果Bean實例不是工廠Bean,或者指定名稱是容器的解引用,//調用者向獲取對容器的引用,則直接返回當前的Bean實例if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}//處理指定名稱不是容器的解引用,或者根據名稱獲取的Bean實例對象是一個工廠Bean//使用工廠Bean創建一個Bean的實例對象Object object = null;if (mbd == null) {//從Bean工廠緩存中獲取給定名稱的Bean實例對象object = getCachedObjectForFactoryBean(beanName);}//讓Bean工廠生產給定名稱的Bean對象實例if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.//如果從Bean工廠生產的Bean是單態模式的,則緩存if (mbd == null && containsBeanDefinition(beanName)) {//從容器中獲取指定名稱的Bean定義,如果繼承基類,則合并基類相關屬性mbd = getMergedLocalBeanDefinition(beanName);}//如果從容器得到Bean定義信息,并且Bean定義信息不是虛構的,//則讓工廠Bean生產Bean實例對象boolean synthetic = (mbd != null && mbd.isSynthetic());//調用FactoryBeanRegistrySupport類的getObjectFromFactoryBean方法,//實現工廠Bean生產Bean對象實例的過程object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object; }在上面獲取給定Bean 的實例對象的getObjectForBeanInstance() 方法中, 會調用FactoryBeanRegistrySupport 類的getObjectFromFactoryBean()方法,該方法實現了Bean 工廠生產Bean 實例對象。
Dereference(解引用):一個在C/C++中應用比較多的術語,在C++中,”*”是解引用符號,而”&”是引用符號,解引用是指變量指向的是所引用對象的本身數據,而不是引用對象的內存地址。
?
?
總結
以上是生活随笔為你收集整理的AbstractBeanFactory 的getBean()方法调用FactoryBean的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FactoryBean 源码
- 下一篇: AbstractBeanFactory