淺談一下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類型的,因為在spring最開始的掃描過程中,給BeanDefiniton 中 beanClass 屬性存入的是對應(yīng) BeanDefinition 的類名稱,下面是 hasBeanClass() 方法的代碼:
public boolean hasBeanClass() {
// 判斷 BeanDefinition 中的 beanClass 屬性是不是屬于 Class 的
// 因為最開始的時候存入的是 BeanDefinition 對應(yīng)的類的類名
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 {
// 加載類,當(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);
}
首先我們注意到方法進入時就有一個獲取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)前類的加載器去加載,有可能返回空,因為 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)被加載了,緊接著就是進入實例化,在實例化前,還有一個步驟就是:實例化前
實例化前
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);
// 如果實例化前,由自己創(chuàng)建類對象則直接返回
if (bean != null) {
return bean;
}
}
// doCreateBean 執(zhí)行創(chuàng)建bean的方法,此方法中就會去實例化對象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
... 省略日志打印
return beanInstance;
..... 省略此步驟無關(guān)代碼
}
這里主要關(guān)注的就是實例化前的 InstantiationAwareBeanPostProcessor 接口,接口中有三個默認的方法,這里只討論,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 初始化前的方法
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
.... 省略另外兩個方法
}
該方法的執(zhí)行時機就是在實例化前,從給出的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) {
// 在實例化前應(yīng)用BeanPostProcessor
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 初始化后的 BeanPostProcessor
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
可以看到在初始化前調(diào)用之后判斷了一次 返回的 bean對象是不是空,因為在初始化前方法中給傳入BeanClass 對象,在此之前就已經(jīng)給 beanClass 賦值過了,這里我們可以自己去創(chuàng)建一個對象返回,如果是這樣,表示不需要Spring來實例化了,并且后續(xù)的Spring依賴注入也不會進行了,會跳過一些步驟,直接執(zhí)行初始化后這一步。在執(zhí)行實例化前這里還有一個小的知識,就是當(dāng)同時存在很多的實例化前 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);
// 因為這里是初始化前,所以在執(zhí)行到 beanPostprocessor 返回有對象的時候就直接返回,不會執(zhí)行后續(xù)的 InstantiationAwareBeanPostProcessor
// 如果第一個處理器就返回了 對象實例,則不會再去執(zhí)行其他的 InstantiationAwareBeanPostProcessor
if (result != null) {
return result;
}
}
return null;
}
在for循環(huán)中 getBeanPostProcessorCache().instantiationAware方法拿到的就是,InstantiationAwareBeanPostProcessor類型的postProcessor,原因是:spring對postProcessor進行了分類的:

下面進入 doCreatebean() 中初始化的流程
實例化
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的實例,默認使用無參構(gòu)造器
* 實例化但是并未初始化,就是沒有給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)增強器修改合并的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 的實例;
此處還有一個 應(yīng)用增強器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)根據(jù)名稱可以知道這是一個操作BeanDefinition的增強器,可以去修改BeanDefinition中的屬性,但是注意這個的執(zhí)行時機,是在 bean 實例化之后在執(zhí)行的,所以說現(xiàn)在修改 BeanDefiniton的有些屬性是無效的,比如beanClss屬性,因為bean已經(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 會認為這是一個工廠方法
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 有機會決定在創(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)造器方式的自動注入
}
// 使用默認的自己設(shè)置的高優(yōu)先級的 構(gòu)造器 Preferred constructors for default construction? // 拿到構(gòu)造器
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 默認使用無參構(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)造方法來進行實例化了。
額外的,在推斷構(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;
}
}
在實例化時,如果判斷出來當(dāng)前BeanDefinition中沒有LookupOverride,那就直接用構(gòu)造方法反射得到一個實例對象。如果存在LookupOverride對象,也就是類中存在@Lookup注解了的方法,那就會生成一個代理對象。
BeanDefionition 的后置處理
Bean對象實例化出來之后,接下來就應(yīng)該給對象的屬性賦值了。在真正給屬性賦值之前,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()
// 設(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()擴展點來實現(xiàn)的,比如我們甚至可以實現(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提供的一個擴展點: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會在初始化前這個步驟中執(zhí)行@PostConstruct的方法,
2.ApplicationContextAwareProcessor會在初始化前這個步驟中進行其他Aware的回調(diào):
- EnvironmentAware:回傳環(huán)境變量
- EmbeddedValueResolverAware:回傳占位符解析器
- ResourceLoaderAware:回傳資源加載器
- ApplicationEventPublisherAware:回傳事件發(fā)布器
- MessageSourceAware:回傳國際化資源
- ApplicationStartupAware:回傳應(yīng)用其他監(jiān)聽對象,可忽略
- 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 的,并且初始化方法有先后執(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對象是否實現(xiàn)了InitializingBean接口,如果實現(xiàn)了就調(diào)用其afterPropertiesSet()方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 檢查是否實現(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 + "'");
}
// 實現(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在初始化后也提供了一個擴展點,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最終進行處理,Spring中的AOP就是基于初始化后實現(xiàn)的,初始化后返回的對象才是最終的Bean對象。
總結(jié)BeanPostProcessor
- InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
- 實例化
- MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
- 自動注入
- InstantiationAwareBeanPostProcessor.postProcessProperties()
- Aware對象
- BeanPostProcessor.postProcessBeforeInitialization()
- 初始化
- BeanPostProcessor.postProcessAfterInitialization()
以上就是淺談一下Spring中的createBean 的詳細內(nèi)容,更多關(guān)于Spring createBean 的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java基于Apache FTP點斷續(xù)傳的文件上傳和下載
本篇文章主要介紹了java基于Apache FTP點斷續(xù)傳的文件上傳和下載,利用FTP實現(xiàn)文件的上傳和下載,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-11-11
不寫mybatis的@Param有的報錯有的卻不報錯問題分析
這篇文章主要為大家介紹了不寫mybatis的@Param有的報錯有的卻不報錯問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
java使用TimeZone將中國標(biāo)準(zhǔn)時間轉(zhuǎn)成時區(qū)值
這篇文章主要介紹了java使用TimeZone將中國標(biāo)準(zhǔn)時間轉(zhuǎn)成時區(qū)值的相關(guān)資料,需要的朋友可以參考下2023-11-11
springboot使用redis實現(xiàn)從配置到實戰(zhàn)
本文主要介紹了springboot使用redis ,采用的是RedisTemplate的形式,還有一種采用spring支持的注解進行訪問緩存,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
解決異常處理問題:getReader()?has?already?been?called?for?this
這篇文章主要介紹了解決異常處理:getReader()?has?already?been?called?for?this問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01

