淺談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源碼中:
-
InitDestroyAnnotationBeanPostProcessor會在初始化前這個步驟中執行@PostConstruct的方法,
-
ApplicationContextAwareProcessor會在初始化前這個步驟中進行其他Aware的回調:
-
- EnvironmentAware:回傳環境變數
- EmbeddedValueResolverAware:回傳佔位符解析器
- ResourceLoaderAware:回傳資源載入器
- ApplicationEventPublisherAware:回傳事件發布器
- MessageSourceAware:回傳國際化資源
- ApplicationStartupAware:回傳應用其他監聽對象,可忽略
- ApplicationContextAware:回傳Spring容器ApplicationContext
-
@PostConstruct @PreDestory 也是在初始化前這一步進行的解析,並做了一個快取
-
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()
bean的銷毀
目前這一塊未總結
如文中又錯誤請指出或者聯繫我:[email protected]