淺談一下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. // 找到需要創(chuàng)建 Bean 對應(yīng)的 Class Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } .......省略與此步驟無關(guān)的代碼 }
注意:上面代碼中的 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(); } // 執(zhí)行搜索 Bean class return doResolveBeanClass(mbd, typesToMatch); } ...省略catch 代碼 } }
注意代碼中有一個 mbd.hasBeanClass() 的判斷, 這個地方比較有迷惑性,并不是判斷beanClass屬性是否存在,而是判斷
beanClass 屬性是不是屬于 Class類型的,因?yàn)樵趕pring最開始的掃描過程中,給BeanDefiniton 中 beanClass 屬性存入的是對應(yīng) BeanDefinition 的類名稱,下面是 hasBeanClass() 方法的代碼:
public boolean hasBeanClass() { // 判斷 BeanDefinition 中的 beanClass 屬性是不是屬于 Class 的 // 因?yàn)樽铋_始的時候存入的是 BeanDefinition 對應(yīng)的類的類名 return (this.beanClass instanceof Class); }
如果判斷 beanClass 屬性 是一個CLass 對象則直接返回,否則進(jìn)入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 自己定義的表達(dá)式---沒有去了解 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 { // 加載類,當(dāng)前 需要創(chuàng)建的 Bean 的 Class文件 return dynamicLoader.loadClass(className); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex); } } } // 內(nèi)部 使用了 Class.forName() 去加載這個類:Class.forName(name, false, clToUse); return ClassUtils.forName(className, dynamicLoader); } } // 定期解析,將結(jié)果緩存在 BeanDefinition 中 // Resolve regularly, caching the result in the BeanDefinition... return mbd.resolveBeanClass(beanClassLoader); }
首先我們注意到方法進(jìn)入時就有一個獲取BeanClassLoader的方法 getBeanClassLoader(),最終該方法的代碼是如下:
@Nullable public static ClassLoader getDefaultClassLoader() { ClassLoader cl = null; try { // 獲取當(dāng)前線程的類加載器,可以設(shè)置的 Thread.currentThread().setContextClassLoader(); cl = Thread.currentThread().getContextClassLoader(); } catch (Throwable ex) { // Cannot access thread context ClassLoader - falling back... } // 使用當(dāng)前類的加載器去加載,有可能返回空,因?yàn)?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 { // 獲取系統(tǒng)的加載器 cl = ClassLoader.getSystemClassLoader(); } catch (Throwable ex) { // Cannot access system ClassLoader - oh well, maybe the caller can live with null... } } } return cl; }
就是拿到類加載器,最終就是使用當(dāng)前的類加載器,去加載mbd.getBeanClassName()
方法拿出來的類名稱className
這樣將 BeanClass 文件就已經(jīng)被加載了,緊接著就是進(jìn)入實(shí)例化,在實(shí)例化前,還有一個步驟就是:實(shí)例化前
實(shí)例化前
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. // 實(shí)例化前 InstantiationAwareBeanPostProcessor 使用的是這個 BeanPostprocessor Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 如果實(shí)例化前,由自己創(chuàng)建類對象則直接返回 if (bean != null) { return bean; } } // doCreateBean 執(zhí)行創(chuàng)建bean的方法,此方法中就會去實(shí)例化對象 Object beanInstance = doCreateBean(beanName, mbdToUse, args); ... 省略日志打印 return beanInstance; ..... 省略此步驟無關(guān)代碼 }
這里主要關(guān)注的就是實(shí)例化前的 InstantiationAwareBeanPostProcessor 接口,接口中有三個默認(rèn)的方法,這里只討論,postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
初始化前的方法
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } .... 省略另外兩個方法 }
該方法的執(zhí)行時機(jī)就是在實(shí)例化前,從給出的createBean方法源碼中可以體現(xiàn)出來,這里就給了我們許多的操作空間。
resolveBeforeInstantiation(beanName, mbdToUse);
在這個方法里面就回去執(zhí)行初始化前的調(diào)用:
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) { // 在實(shí)例化前應(yīng)用BeanPostProcessor bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 初始化后的 BeanPostProcessor bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
可以看到在初始化前調(diào)用之后判斷了一次 返回的 bean對象是不是空,因?yàn)樵诔跏蓟胺椒ㄖ薪o傳入BeanClass 對象,在此之前就已經(jīng)給 beanClass 賦值過了,這里我們可以自己去創(chuàng)建一個對象返回,如果是這樣,表示不需要Spring來實(shí)例化了,并且后續(xù)的Spring依賴注入也不會進(jìn)行了,會跳過一些步驟,直接執(zhí)行初始化后這一步。在執(zhí)行實(shí)例化前這里還有一個小的知識,就是當(dāng)同時存在很多的實(shí)例化前 postProcessor ,只要一直行到 postProcessBeforeInstantiation
方法返回的bean不是空的的情況下,剩下所有的 初始化前postProcessor都不會在執(zhí)行了。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { // 這里拿到的就是 InstantiationAwareBeanPostProcessor 類型的 postProcessor for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); // 因?yàn)檫@里是初始化前,所以在執(zhí)行到 beanPostprocessor 返回有對象的時候就直接返回,不會執(zhí)行后續(xù)的 InstantiationAwareBeanPostProcessor // 如果第一個處理器就返回了 對象實(shí)例,則不會再去執(zhí)行其他的 InstantiationAwareBeanPostProcessor if (result != null) { return result; } } return null; }
在for循環(huán)中 getBeanPostProcessorCache().instantiationAware
方法拿到的就是,InstantiationAwareBeanPostProcessor
類型的postProcessor,原因是:spring對postProcessor進(jìn)行了分類的:
下面進(jìn)入 doCreatebean() 中初始化的流程
實(shí)例化
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. // BeanWrapper:持有創(chuàng)建出來的Bean BeanWrapper instanceWrapper = null; // 判斷當(dāng)前的bean定義是否為單例 if (mbd.isSingleton()) { // 有可能在本 Bean 創(chuàng)建之前就已經(jīng)把當(dāng)前 Bean 給創(chuàng)建出來了(比如在依賴注入過程中) instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 從工廠bean緩存中移除 }// 不為空則 代表為 FactoryBean 已經(jīng)創(chuàng)建過,存在緩存中 if (instanceWrapper == null) { /** * 創(chuàng)建bean的實(shí)例,默認(rèn)使用無參構(gòu)造器 * 實(shí)例化但是并未初始化,就是沒有給bean的屬性復(fù)制 * 組建的原始對象就創(chuàng)建了 */ 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)增強(qiáng)器修改合并的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);
此方法就是去創(chuàng)建 bean 的實(shí)例;
此處還有一個 應(yīng)用增強(qiáng)器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
根據(jù)名稱可以知道這是一個操作BeanDefinition
的增強(qiáng)器,可以去修改BeanDefinition
中的屬性,但是注意這個的執(zhí)行時機(jī),是在 bean 實(shí)例化之后在執(zhí)行的,所以說現(xiàn)在修改 BeanDefiniton
的有些屬性是無效的,比如beanClss屬性,因?yàn)閎ean已經(jīng)創(chuàng)建了。
此處的 PostProcessor
的類型為:MergedBeanDefinitionPostProcessor
。
Supplier創(chuàng)建對象
首先判斷BeanDefinition中是否設(shè)置了Supplier,如果設(shè)置了則調(diào)用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的提供者 ,存在就使用提供者創(chuàng)建對象:這是一個函數(shù)式接口 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { // 存在 bean 的提供者,則直接調(diào)用 Supplier 的 get() 方法拿到對象 return obtainFromSupplier(instanceSupplier, beanName); } // 使用工廠方法、例如:@Bean注解放在方法上,返回值注入容器,spring 會認(rèn)為這是一個工廠方法 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 有機(jī)會決定在創(chuàng)建對象錢使用那個構(gòu)造器 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); //有自己指定的構(gòu)造器: 構(gòu)造器方式的自動注入 } // 使用默認(rèn)的自己設(shè)置的高優(yōu)先級的 構(gòu)造器 Preferred constructors for default construction? // 拿到構(gòu)造器 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // 默認(rèn)使用無參構(gòu)造器 // No special handling: simply use no-arg constructor. 無需特殊處理:使用簡單的無參構(gòu)造器 return instantiateBean(beanName, mbd); }
工廠方法創(chuàng)建對象
方法一
如果沒有設(shè)置Supplier,則檢查BeanDefinition中是否設(shè)置了factoryMethod,也就是工廠方法,有兩種方式可以設(shè)置factoryMethod,比如:
<bean id="userService" class="cn.baldhead.service.UserService" factory-method="createUserService" />
對應(yīng)的UserService 代碼
public class UserService { public static UserService createUserService() { System.out.println("執(zhí)行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發(fā)現(xiàn)當(dāng)前BeanDefinition方法設(shè)置了工廠方法后,就會區(qū)分這兩種方式,然后調(diào)用工廠方法得到對象。
值得注意的是,我們通過@Bean所定義的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常類似,@Bean所注解的方法就是factoryMethod,AppConfig對象就是factoryBean。如果@Bean所所注解的方法是static的,那么對應(yīng)的就是方式一。
推斷構(gòu)造方法
推斷完構(gòu)造方法后,就會使用構(gòu)造方法來進(jìn)行實(shí)例化了。
額外的,在推斷構(gòu)造方法邏輯中除開會去選擇構(gòu)造方法以及查找入?yún)ο笠馔?,會還判斷是否在對應(yīng)的類中是否存在使用@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; } }
在實(shí)例化時,如果判斷出來當(dāng)前BeanDefinition中沒有LookupOverride,那就直接用構(gòu)造方法反射得到一個實(shí)例對象。如果存在LookupOverride對象,也就是類中存在@Lookup注解了的方法,那就會生成一個代理對象。
BeanDefionition 的后置處理
Bean對象實(shí)例化出來之后,接下來就應(yīng)該給對象的屬性賦值了。在真正給屬性賦值之前,Spring又提供了一個擴(kuò)展點(diǎn)MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
,可以對此時的BeanDefinition進(jìn)行加工,比如:
@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)增強(qiáng)器修改合并的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()中會去查找注入點(diǎn),并緩存在AutowiredAnnotationBeanPostProcessor對象的一個Map中(injectionMetadataCache)。
實(shí)例化后
AbstractAutowireCapableBeanFactory.poputlateBean()
// 設(shè)置屬性注入 之前bean的狀態(tài),例如,屬性賦值之前后置處理器可以提前處理些東西 // 支持字段注入 (但是在此處什么事都沒做) if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } }
屬性填充
AbstractAutowireCapableBeanFactory.populateBean()
spring的注入
? 必須要有對應(yīng)屬性的set方法,type:根據(jù)參數(shù)的類型去找到對應(yīng)的Bean,name:根據(jù)方法setxxx后面的一串去找到對應(yīng)的 Bean ,例如當(dāng)前就是用的 xxx 作為name去找
只要是set 方法 Spring 都會去調(diào)用,不管這個set方法是做什么的,都會去調(diào)用
? 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. 通過名稱自動注入?yún)?shù)的值 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. 通過類型注入?yún)?shù)的值 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; }
自動注入
處理屬性
這個步驟中,就會處理@Autowired、@Resource、@Value等注解,也是通過InstantiationAwareBeanPostProcessor.postProcessProperties()
擴(kuò)展點(diǎn)來實(shí)現(xiàn)的,比如我們甚至可以實(shí)現(xiàn)一個自己的自動注入功能,比如:
@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回調(diào)
AbstractAutowireCapableBeanFactory.initializeBean(..);
回調(diào)執(zhí)行Aware接口
完成了屬性賦值之后,Spring會執(zhí)行一些回調(diào),包括:
BeanNameAware
:回傳beanName給bean對象。BeanClassLoaderAware
:回傳classLoader給bean對象。BeanFactoryAware
:回傳beanFactory給對象。
初始化前
初始化前,也是Spring提供的一個擴(kuò)展點(diǎn):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; } }
利用初始化前,可以對進(jìn)行了依賴注入的Bean進(jìn)行處理。
在Spring源碼中:
1.InitDestroyAnnotationBeanPostProcessor會在初始化前這個步驟中執(zhí)行@PostConstruct的方法,
2.ApplicationContextAwareProcessor會在初始化前這個步驟中進(jìn)行其他Aware的回調(diào):
- EnvironmentAware:回傳環(huán)境變量
- EmbeddedValueResolverAware:回傳占位符解析器
- ResourceLoaderAware:回傳資源加載器
- ApplicationEventPublisherAware:回傳事件發(fā)布器
- MessageSourceAware:回傳國際化資源
- ApplicationStartupAware:回傳應(yīng)用其他監(jiān)聽對象,可忽略
- ApplicationContextAware:回傳Spring容器ApplicationContext
4.@PostConstruct @PreDestory 也是在初始化前這一步進(jìn)行的解析,并做了一個緩存
5.InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata()
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) { return this.emptyLifecycleMetadata; } // 這里面就會有 @PostConstruct 的,并且初始化方法有先后執(zhí)行順序,父類的排在前面,子類的在后面 // 父類優(yōu)先執(zhí)行 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); } } }); // 父類的初始化方法在前,也就是有一個先后順序,先執(zhí)行父類的 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)); }
初始化
查看當(dāng)前Bean對象是否實(shí)現(xiàn)了InitializingBean接口,如果實(shí)現(xiàn)了就調(diào)用其afterPropertiesSet()方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { // 檢查是否實(shí)現(xiàn)了 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 + "'"); } // 實(shí)現(xiàn)了 InitializingBean 接口,執(zhí)行調(diào)用 afterPropertiesSet 方法 // 使用了多態(tài)的操作方式 將 bean 轉(zhuǎn)換為一個接口(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)) { // 執(zhí)行自定一個init-method方法,通過反射 method.invoke() invokeCustomInitMethod(beanName, bean, mbd); } } }
執(zhí)行BeanDefinition中指定的初始化方法
mbd.getInitMethodName()
初始化后
spring
在初始化后也提供了一個擴(kuò)展點(diǎn),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()) { // 初始化后執(zhí)行,postProcessor wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
可以在這個步驟中,對Bean最終進(jìn)行處理,Spring中的AOP就是基于初始化后實(shí)現(xiàn)的,初始化后返回的對象才是最終的Bean對象。
總結(jié)BeanPostProcessor
- InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
- 實(shí)例化
- MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
- 自動注入
- InstantiationAwareBeanPostProcessor.postProcessProperties()
- Aware對象
- BeanPostProcessor.postProcessBeforeInitialization()
- 初始化
- BeanPostProcessor.postProcessAfterInitialization()
以上就是淺談一下Spring中的createBean 的詳細(xì)內(nèi)容,更多關(guān)于Spring createBean 的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java基于Apache FTP點(diǎn)斷續(xù)傳的文件上傳和下載
本篇文章主要介紹了java基于Apache FTP點(diǎn)斷續(xù)傳的文件上傳和下載,利用FTP實(shí)現(xiàn)文件的上傳和下載,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-11-11IDEA生成servlet程序的實(shí)現(xiàn)步驟
這篇文章主要介紹了IDEA生成servlet程序的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03不寫mybatis的@Param有的報錯有的卻不報錯問題分析
這篇文章主要為大家介紹了不寫mybatis的@Param有的報錯有的卻不報錯問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09java使用TimeZone將中國標(biāo)準(zhǔn)時間轉(zhuǎn)成時區(qū)值
這篇文章主要介紹了java使用TimeZone將中國標(biāo)準(zhǔn)時間轉(zhuǎn)成時區(qū)值的相關(guān)資料,需要的朋友可以參考下2023-11-11springboot使用redis實(shí)現(xiàn)從配置到實(shí)戰(zhàn)
本文主要介紹了springboot使用redis ,采用的是RedisTemplate的形式,還有一種采用spring支持的注解進(jìn)行訪問緩存,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08解決異常處理問題:getReader()?has?already?been?called?for?this
這篇文章主要介紹了解決異常處理:getReader()?has?already?been?called?for?this問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01