開篇
?在Spring 獲取Bean流程文章中已經梳理了getBean的整個過程句伶,這篇文章主要著重講講Bean的創(chuàng)建過程,順便著梳理下init-method魁亦、afterPropertiesSet、postProcessBeforeInitialization、postProcessAfterInitialization的調用過程缩举。
調用順序
<bean id="sampleBean" class="com.lntea.spring.demo.bean.SampleBean" init-method="prepare"></bean>
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
說明
初始化過程中執(zhí)行的順序:
- BeanPostProcessor的初始化前置回調方法postProcessBeforeInitialization()。
- InitializingBean接口的初始化方法afterPropertiesSet()匹颤。
- init-method初始化方法仅孩。
- BeanPostProcessor的初始化后置回調方法postProcessAfterInitialization()。
Bean創(chuàng)建流程
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 解析指定 BeanDefinition 的 class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 驗證和準備覆蓋方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
}
try {
// 給 BeanPostProcessors 一個機會用來返回一個代理類而不是真正的類實例
// AOP 的功能就是基于這個地方
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
}
try {
// 執(zhí)行真正創(chuàng)建 bean 的過程
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
}
catch (Throwable ex) {
}
}
}
說明:
- 1印蓖、首先解析指定 BeanDefinition的class辽慕。
- 2、處理BeanDefinition里面的 override 屬性赦肃。
- 3溅蛉、實例化的前置處理BeanPostProcessor接口。
- 4他宛、執(zhí)行根據BeanDefinition創(chuàng)建bean過程船侧。
執(zhí)行Bean創(chuàng)建過程
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 使用合適的實例化策略來創(chuàng)建新的實例:工廠方法、構造函數自動注入堕汞、簡單初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 檢測是否有后置處理
// 如果有后置處理勺爱,則允許后置處理修改 BeanDefinition
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;
}
}
// 解決單例模式的循環(huán)依賴
// 單例模式 & 運行循環(huán)依賴&當前單例 bean 是否正在被創(chuàng)建
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 開始初始化 bean 實例對象
Object exposedObject = bean;
try {
// 對 bean 進行填充,將各個屬性值注入讯检,其中琐鲁,可能存在依賴于其他 bean 的屬性
// 則會遞歸初始依賴 bean
populateBean(beanName, mbd, instanceWrapper);
// 調用初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
}
/**
* 循環(huán)依賴處理
*/
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
}
}
}
// 注冊 bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
}
return exposedObject;
}
}
說明:
- 5、MergedBeanDefinitionPostProcessor 的應用人灼。
- 6围段、單例模式的循環(huán)依賴處理。
- 7投放、調用 populateBean() 進行屬性填充奈泪。將所有屬性填充至 bean 的實例中。
- 8、 調用 initializeBean() 初始化 bean涝桅。
- 9拜姿、依賴檢查。
- 10冯遂、通過registerDisposableBeanIfNecessary注冊 DisposableBean蕊肥。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 初始化前置回調方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
}
if (mbd == null || !mbd.isSynthetic()) {
// 初始化后置回調方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 批量初始化的后置方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
說明:
- 11、初始化前置回調方法蛤肌。
- 12壁却、初始化方法。
- 13裸准、初始化后置回調方法展东。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
}
說明:
- 14、執(zhí)行afterPropertiesSet()方法炒俱。
- 15盐肃、執(zhí)行invokeCustomInitMethod的init-method方法。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
String initMethodName = mbd.getInitMethodName();
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
methodToInvoke.invoke(bean), getAccessControlContext());
}
catch (PrivilegedActionException pae) {
}
}
else {
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
說明:
- 16向胡、通過反射調用init-method方法恼蓬。