如果你正打算深入學習Spring,但是不知從何學起,那么我強烈推薦你可以按照這個系列做一遍。本系列將Spring框架的各個部分從它龐雜的代碼體系中抽取出來,然后對每一個部分進行講解,并最終搭建成簡易版Spring。我以人格保證:如果你可以堅持做下來,那么你對Spring這塊的知識就基本都掌握清楚了! 附上該系列地址:https://blog.csdn.net/zhang_qing_yun/article/details/120084497# getBean的流程 ## 源碼
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException { // getBean 其實沒做啥,都在 doGetBean 里return doGetBean(name, requiredType, null, false);
}
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException { // 處理別名BeanName、處理帶&符的工廠BeanNamefinal 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 + "'");}} // 1. 如果 sharedInstance 是普通的 Bean 實例,則下面的方法會直接返回// 2. 如果 sharedInstance 是工廠Bean類型,則需要獲取 getObject 方法,可以參考關于 FactoryBean 的實現類 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 循環依賴有三種,setter注入、多實例和構造函數,Spring 只能解決 setter 注入,所以這里是 Prototype 則會拋出異常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);} // 1. 父 bean 工廠存在// 2. 當前 bean 不存在于當前bean工廠,則到父工廠查找 bean 實例BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// 獲取 name 對應的 beanName,如果 name 是以 & 開頭,則返回 & + beanNameString nameToLookup = originalBeanName(name); // 根據 args 參數是否為空,調用不同的父容器方法獲取 bean 實例if (args != null) {return (T) parentBeanFactory.getBean(nameToLookup, args);}else {return parentBeanFactory.getBean(nameToLookup, requiredType);}} // 1. typeCheckOnly,用于判斷調用 getBean 方法時,是否僅是做類型檢查// 2. 如果不是只做類型檢查,就會調用 markBeanAsCreated 進行記錄if (!typeCheckOnly) {markBeanAsCreated(beanName);}try { // 從容器 getMergedLocalBeanDefinition 獲取 beanName 對應的 GenericBeanDefinition,轉換為 RootBeanDefinitionfinal RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 檢查當前創建的 bean 定義是否為抽象 bean 定義checkMergedBeanDefinition(mbd, beanName, args);// 處理使用了 depends-on 注解的依賴創建 bean 實例String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) { // 監測是否存在 depends-on 循環依賴,若存在則會拋出異常if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");} // 注冊依賴記錄registerDependentBean(dep, beanName);try { // 加載 depends-on 依賴(dep 是 depends-on 縮寫)getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}} // 創建單例 bean 實例if (mbd.isSingleton()) { // 把 beanName 和 new ObjectFactory 匿名內部類傳入回調sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try { // 創建 beanreturn createBean(beanName, mbd, args);}catch (BeansException ex) {// 創建失敗則銷毀destroySingleton(beanName);throw ex;}}});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);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>() {@Overridepublic 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;}}// 如果需要類型轉換,這里會進行操作if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {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());}} // 返回 Beanreturn (T) bean;
}
幾個重要函數:
protected String transformedBeanName(String name) {//如果beanName是以&開頭的 則截取掉開頭的&return canonicalName(BeanFactoryUtils.transformedBeanName(name));}public String canonicalName(String name) {String canonicalName = name;// 循環的去獲取別名,直到獲取到真實的beanName//aliasA->aliasB->beanNameString resolvedName;do {resolvedName = this.aliasMap.get(canonicalName);if (resolvedName != null) {canonicalName = resolvedName;}}while (resolvedName != null);return canonicalName;}
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {//如果name是以&開頭的 但是不是FactoryBean,則直接拋出異常if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());}// 則beanInstance可能是一個普通的bean,也可能是一個FactoryBean// 如果是一個普通的bean,則直接返回if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}//FactoryBean創建出bean實例返回Object object = null;if (mbd == null) {object = getCachedObjectForFactoryBean(beanName);}if (object == null) {FactoryBean<?> factory = (FactoryBean<?>) beanInstance;if (mbd == null && containsBeanDefinition(beanName)) {mbd = getMergedLocalBeanDefinition(beanName);}boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}
&
符號用來和普通Bean的BeanName區分,但是在存儲上沒有差異),另一個是針對別名的處理,將其替換為真實的BeanName。版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态