淺談一下Spring中的createBean

找到BeanClass並且加載類

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("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.
		// 找到需要創建 Bean 對應的 Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
  .......省略與此步驟無關的代碼
}

註意:上面代碼中的 resolveBeanClass(mbd, beanName) 方法,就是去查找BeanClass的,下面看看 resolveBeanClass 方法的代碼

@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
      throws CannotLoadBeanClassException {

   try {
      // 判斷 BeanDefinition 中的 beanClass 屬性是不是 Class 類型的
      if (mbd.hasBeanClass()) {
         return mbd.getBeanClass();
      }
      // 執行搜索 Bean class
      return doResolveBeanClass(mbd, typesToMatch);
   }  ...省略catch 代碼
   }
}

註意代碼中有一個 mbd.hasBeanClass() 的判斷, 這個地方比較有迷惑性,並不是判斷beanClass屬性是否存在,而是判斷

beanClass 屬性是不是屬於 Class類型的,因為在spring最開始的掃描過程中,給BeanDefiniton 中 beanClass 屬性存入的是對應 BeanDefinition 的類名稱,下面是 hasBeanClass() 方法的代碼:

public boolean hasBeanClass() {

   // 判斷 BeanDefinition 中的 beanClass 屬性是不是屬於 Class 的
   // 因為最開始的時候存入的是 BeanDefinition 對應的類的類名
   return (this.beanClass instanceof Class);
}

如果判斷 beanClass 屬性 是一個CLass 對象則直接返回,否則進入doResolceBeanClass(mad, typesToMatch) 方法

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
      throws ClassNotFoundException {

   // 獲取類加載器
   ClassLoader beanClassLoader = getBeanClassLoader();
   ClassLoader dynamicLoader = beanClassLoader;
   boolean freshResolve = false;

   .... 省略代碼
     
   // 這裡就是拿的 RootBeanDefinition 中的 beanClass屬性
   String className = mbd.getBeanClassName();
   if (className != null) {
      // 解析 spring 自己定義的表達式---沒有去瞭解
      Object evaluated = evaluateBeanDefinitionString(className, mbd);
      if (!className.equals(evaluated)) {
         // A dynamically resolved expression, supported as of 4.2...
         if (evaluated instanceof Class) {
            return (Class<?>) evaluated;
         } else if (evaluated instanceof String) {
            className = (String) evaluated;
            freshResolve = true;
         } else {
            throw new IllegalStateException("Invalid class name expression result: " + evaluated);
         }
      }
      if (freshResolve) {
         // When resolving against a temporary class loader, exit early in order
         // to avoid storing the resolved Class in the bean definition.
         if (dynamicLoader != null) {
            try {
               // 加載類,當前 需要創建的 Bean 的 Class文件
               return dynamicLoader.loadClass(className);
            } catch (ClassNotFoundException ex) {
               if (logger.isTraceEnabled()) {
                  logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
               }
            }
         }
        	// 內部 使用瞭 Class.forName() 去加載這個類:Class.forName(name, false, clToUse);
         return ClassUtils.forName(className, dynamicLoader);
      }
   }
   // 定期解析,將結果緩存在 BeanDefinition 中
   // Resolve regularly, caching the result in the BeanDefinition...
   return mbd.resolveBeanClass(beanClassLoader);
}

首先我們註意到方法進入時就有一個獲取BeanClassLoader的方法 getBeanClassLoader(),最終該方法的代碼是如下:

@Nullable
public static ClassLoader getDefaultClassLoader() {
   ClassLoader cl = null;
   try {
      // 獲取當前線程的類加載器,可以設置的 Thread.currentThread().setContextClassLoader();
      cl = Thread.currentThread().getContextClassLoader();
   }
   catch (Throwable ex) {
      // Cannot access thread context ClassLoader - falling back...
   }
  // 使用當前類的加載器去加載,有可能返回空,因為 lib 下面的 jar包使用 bootstrap 類加載器去加載的
   if (cl == null) {
      // No thread context class loader -> use class loader of this class.
      cl = ClassUtils.class.getClassLoader();
      if (cl == null) {
         // getClassLoader() returning null indicates the bootstrap ClassLoader
         try {
            // 獲取系統的加載器
            cl = ClassLoader.getSystemClassLoader();
         }
         catch (Throwable ex) {
            // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
         }
      }
   }
   return cl;
}

就是拿到類加載器,最終就是使用當前的類加載器,去加載mbd.getBeanClassName()方法拿出來的類名稱className

這樣將 BeanClass 文件就已經被加載瞭,緊接著就是進入實例化,在實例化前,還有一個步驟就是:實例化前

實例化前

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

	...... 省略上一步驟的代碼

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      // 實例化前  InstantiationAwareBeanPostProcessor  使用的是這個 BeanPostprocessor
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      // 如果實例化前,由自己創建類對象則直接返回
      if (bean != null) {
         return bean;
      }
   }
  	// doCreateBean 執行創建bean的方法,此方法中就會去實例化對象
  Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		... 省略日志打印
			return beanInstance;
  ..... 省略此步驟無關代碼
}

這裡主要關註的就是實例化前的 InstantiationAwareBeanPostProcessor 接口,接口中有三個默認的方法,這裡隻討論,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 初始化前的方法

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
  .... 省略另外兩個方法
}

該方法的執行時機就是在實例化前,從給出的createBean方法源碼中可以體現出來,這裡就給瞭我們許多的操作空間。

resolveBeforeInstantiation(beanName, mbdToUse); 在這個方法裡面就回去執行初始化前的調用:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            // 在實例化前應用BeanPostProcessor
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               // 初始化後的 BeanPostProcessor
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

可以看到在初始化前調用之後判斷瞭一次 返回的 bean對象是不是空,因為在初始化前方法中給傳入BeanClass 對象,在此之前就已經給 beanClass 賦值過瞭,這裡我們可以自己去創建一個對象返回,如果是這樣,表示不需要Spring來實例化瞭,並且後續的Spring依賴註入也不會進行瞭,會跳過一些步驟,直接執行初始化後這一步。在執行實例化前這裡還有一個小的知識,就是當同時存在很多的實例化前 postProcessor ,隻要一直行到 postProcessBeforeInstantiation 方法返回的bean不是空的的情況下,剩下所有的 初始化前postProcessor都不會在執行瞭。

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 這裡拿到的就是 InstantiationAwareBeanPostProcessor 類型的 postProcessor
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			// 因為這裡是初始化前,所以在執行到 beanPostprocessor 返回有對象的時候就直接返回,不會執行後續的 InstantiationAwareBeanPostProcessor
			// 如果第一個處理器就返回瞭 對象實例,則不會再去執行其他的 InstantiationAwareBeanPostProcessor
			if (result != null) {
				return result;
			}
		}
		return null;
	}

在for循環中 getBeanPostProcessorCache().instantiationAware方法拿到的就是,InstantiationAwareBeanPostProcessor類型的postProcessor,原因是:spring對postProcessor進行瞭分類的:

下面進入 doCreatebean() 中初始化的流程

實例化

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   // BeanWrapper:持有創建出來的Bean
   BeanWrapper instanceWrapper = null;
   // 判斷當前的bean定義是否為單例
   if (mbd.isSingleton()) {
      // 有可能在本 Bean 創建之前就已經把當前 Bean 給創建出來瞭(比如在依賴註入過程中)
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 從工廠bean緩存中移除
   }// 不為空則  代表為 FactoryBean 已經創建過,存在緩存中
   if (instanceWrapper == null) {
      /**
       * 創建bean的實例,默認使用無參構造器
       * 實例化但是並未初始化,就是沒有給bean的屬性復制
       * 組建的原始對象就創建瞭
       */
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   // 允許(MergedBeanDefinitionPostProcessor)增強器修改合並的bean definition 修改BD信息
   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;
      }
   }
  ...... 省略代碼 ......
}

createBeanInstance(beanName, mbd, args);此方法就是去創建 bean 的實例;

此處還有一個 應用增強器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)根據名稱可以知道這是一個操作BeanDefinition的增強器,可以去修改BeanDefinition中的屬性,但是註意這個的執行時機,是在 bean 實例化之後在執行的,所以說現在修改 BeanDefiniton的有些屬性是無效的,比如beanClss屬性,因為bean已經創建瞭。

此處的 PostProcessor的類型為:MergedBeanDefinitionPostProcessor

Supplier創建對象

首先判斷BeanDefinition中是否設置瞭Supplier,如果設置瞭則調用Supplier的get()得到對象。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // 拿到bean 的 class  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());
   }
   // 定義bean的提供者  ,存在就使用提供者創建對象:這是一個函數式接口
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
     	// 存在 bean 的提供者,則直接調用 Supplier 的 get() 方法拿到對象
			return obtainFromSupplier(instanceSupplier, beanName);
   }
 // 使用工廠方法、例如:@Bean註解放在方法上,返回值註入容器,spring 會認為這是一個工廠方法
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		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);
			}
		}

		// 後置處理器 SmartInstantiationAwareBeanPostProcessor 有機會決定在創建對象錢使用那個構造器 Candidate constructors for autowiring?
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args); //有自己指定的構造器: 構造器方式的自動註入
		}

		// 使用默認的自己設置的高優先級的 構造器 Preferred constructors for default construction? // 拿到構造器
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}
		// 默認使用無參構造器
		// No special handling: simply use no-arg constructor. 無需特殊處理:使用簡單的無參構造器
		return instantiateBean(beanName, mbd);
}

工廠方法創建對象

方法一

如果沒有設置Supplier,則檢查BeanDefinition中是否設置瞭factoryMethod,也就是工廠方法,有兩種方式可以設置factoryMethod,比如:

<bean id="userService" class="cn.baldhead.service.UserService" factory-method="createUserService" />

對應的UserService 代碼

public class UserService {

	public static UserService createUserService() {
		System.out.println("執行createUserService()");
		UserService userService = new UserService();
		return userService;
	}

	public void test() {
		System.out.println("test");
	}

}

方法二

<bean id="commonService" class="cn.baldhead.service.CommonService"/>
<bean id="userService1" factory-bean="commonService" factory-method="createUserService" />

Spring發現當前BeanDefinition方法設置瞭工廠方法後,就會區分這兩種方式,然後調用工廠方法得到對象。

值得註意的是,我們通過@Bean所定義的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常類似,@Bean所註解的方法就是factoryMethod,AppConfig對象就是factoryBean。如果@Bean所所註解的方法是static的,那麼對應的就是方式一。

推斷構造方法

推斷完構造方法後,就會使用構造方法來進行實例化瞭。

額外的,在推斷構造方法邏輯中除開會去選擇構造方法以及查找入參對象意外,會還判斷是否在對應的類中是否存在使用@Lookup註解瞭方法。如果存在則把該方法封裝為LookupOverride對象並添加到BeanDefinition中。

@Lookup註解就是方法註入,例如demo如下:

@Component
public class UserService {

	private OrderService orderService;

	public void test() {
		OrderService orderService = createOrderService();
		System.out.println(orderService);
	}

	@Lookup("orderService")
	public OrderService createOrderService() {
		return null;
	}

}

在實例化時,如果判斷出來當前BeanDefinition中沒有LookupOverride,那就直接用構造方法反射得到一個實例對象。如果存在LookupOverride對象,也就是類中存在@Lookup註解瞭的方法,那就會生成一個代理對象。

BeanDefionition 的後置處理

Bean對象實例化出來之後,接下來就應該給對象的屬性賦值瞭。在真正給屬性賦值之前,Spring又提供瞭一個擴展點MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以對此時的BeanDefinition進行加工,比如:

@Component
public class BaldHeadMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 可以手動給 beanDefinition 得ptopertyValues 添加一個屬性賦值,屬性名-值(bean中的屬性賦值)
		if ("baldHeadService".equals(beanName)) {
			beanDefinition.getPropertyValues().add("orderService", new OrderService());
		}
	}
}

源碼在–doCreateBean()

/ Allow post-processors to modify the merged bean definition.
		// 允許(MergedBeanDefinitionPostProcessor)增強器修改合並的bean definition 修改BD信息
		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;
			}
		}

在Spring源碼中,AutowiredAnnotationBeanPostProcessor就是一個MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中會去查找註入點,並緩存在AutowiredAnnotationBeanPostProcessor對象的一個Map中(injectionMetadataCache)。

實例化後

AbstractAutowireCapableBeanFactory.poputlateBean()

// 設置屬性註入   之前bean的狀態,例如,屬性賦值之前後置處理器可以提前處理些東西
// 支持字段註入  (但是在此處什麼事都沒做)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
         return;
      }
   }
}

屬性填充

AbstractAutowireCapableBeanFactory.populateBean()

spring的註入

​ 必須要有對應屬性的set方法,type:根據參數的類型去找到對應的Bean,name:根據方法setxxx後面的一串去找到對應的 Bean ,例如當前就是用的 xxx 作為name去找

隻要是set 方法 Spring 都會去調用,不管這個set方法是做什麼的,都會去調用

​ BY_TYPE,BY_NAME

	// 獲取所有屬性的值
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable. 通過名稱自動註入參數的值
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable. 通過類型註入參數的值
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

自動註入

處理屬性

這個步驟中,就會處理@Autowired、@Resource、@Value等註解,也是通過InstantiationAwareBeanPostProcessor.postProcessProperties()擴展點來實現的,比如我們甚至可以實現一個自己的自動註入功能,比如:

@Component
public class BaldHeadInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
		if ("baldHeadService".equals(beanName)) {
			for (Field field : bean.getClass().getFields()) {
				if (field.isAnnotationPresent(BaldHeadInject.class)) {
					field.setAccessible(true);
					try {
						field.set(bean, "123");
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
		}

		return pvs;
	}
}

Aware回調

AbstractAutowireCapableBeanFactory.initializeBean(..);

回調執行Aware接口

完成瞭屬性賦值之後,Spring會執行一些回調,包括:

  • BeanNameAware:回傳beanName給bean對象。
  • BeanClassLoaderAware:回傳classLoader給bean對象。
  • BeanFactoryAware:回傳beanFactory給對象。

初始化前

初始化前,也是Spring提供的一個擴展點:BeanPostProcessor.postProcessBeforeInitialization(),比如

@Component
public class BaldHeadBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if ("baldHeadService".equals(beanName)) {
			System.out.println("初始化前");
		}

		return bean;
	}
}

利用初始化前,可以對進行瞭依賴註入的Bean進行處理。

在Spring源碼中:

1.InitDestroyAnnotationBeanPostProcessor會在初始化前這個步驟中執行@PostConstruct的方法,

2.ApplicationContextAwareProcessor會在初始化前這個步驟中進行其他Aware的回調:

  • EnvironmentAware:回傳環境變量
  • EmbeddedValueResolverAware:回傳占位符解析器
  • ResourceLoaderAware:回傳資源加載器
  • ApplicationEventPublisherAware:回傳事件發佈器
  • MessageSourceAware:回傳國際化資源
  • ApplicationStartupAware:回傳應用其他監聽對象,可忽略
  • ApplicationContextAware:回傳Spring容器ApplicationContext

4.@PostConstruct @PreDestory 也是在初始化前這一步進行的解析,並做瞭一個緩存

5.InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata()

	private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
			return this.emptyLifecycleMetadata;
		}

        // 這裡面就會有 @PostConstruct 的,並且初始化方法有先後執行順序,父類的排在前面,子類的在後面
        // 父類優先執行
		List<LifecycleElement> initMethods = new ArrayList<>();
        // 這裡面會有 @PreDestroy 的
		List<LifecycleElement> destroyMethods = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<LifecycleElement> currInitMethods = new ArrayList<>();
			final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
					LifecycleElement element = new LifecycleElement(method);
					currInitMethods.add(element);
					if (logger.isTraceEnabled()) {
						logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
					}
				}
				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
					currDestroyMethods.add(new LifecycleElement(method));
					if (logger.isTraceEnabled()) {
						logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
					}
				}
			});
			// 父類的初始化方法在前,也就是有一個先後順序,先執行父類的 init-method 方法
			initMethods.addAll(0, currInitMethods);
			destroyMethods.addAll(currDestroyMethods);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
				new LifecycleMetadata(clazz, initMethods, destroyMethods));
	}

初始化

查看當前Bean對象是否實現瞭InitializingBean接口,如果實現瞭就調用其afterPropertiesSet()方法

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
		// 檢查是否實現瞭 InitializingBean 接口
		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			// 實現瞭 InitializingBean 接口,執行調用 afterPropertiesSet 方法
			// 使用瞭多態的操作方式 將 bean 轉換為一個接口(initializingBean)
			((InitializingBean) bean).afterPropertiesSet();
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			// 獲取自定一個init-method方法
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				// 執行自定一個init-method方法,通過反射 method.invoke()
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

執行BeanDefinition中指定的初始化方法

mbd.getInitMethodName()

初始化後

spring在初始化後也提供瞭一個擴展點,BeanPostProcessor.postProcessAfterInitialization()->例如:

@Component
public class BaldHeadBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if ("baldHeadService".equals(beanName)) {
			System.out.println("初始化後");
		}

		return bean;
	}
}
if (mbd == null || !mbd.isSynthetic()) { // 初始化後執行,postProcessor
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

可以在這個步驟中,對Bean最終進行處理,Spring中的AOP就是基於初始化後實現的,初始化後返回的對象才是最終的Bean對象

總結BeanPostProcessor

  • InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
  • 實例化
  • MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
  • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
  • 自動註入
  • InstantiationAwareBeanPostProcessor.postProcessProperties()
  • Aware對象
  • BeanPostProcessor.postProcessBeforeInitialization()
  • 初始化
  • BeanPostProcessor.postProcessAfterInitialization()

以上就是淺談一下Spring中的createBean 的詳細內容,更多關於Spring createBean 的資料請關註WalkonNet其它相關文章!

推薦閱讀: