知識回顧
Bean的創建程序會經歷getBean,doGetBean,createBean,doCreateBean,然后Bean的創建又會經歷實體化,屬性填充,初始化,
在實體化createInstance時大致可以分為三種方式進行實體化:
- 使用
Supplier進行實體化,通過BeanFactoryPostProcessor對BeanDefinition進行修改,增加一個Supplier屬性,放置一個lambda運算式用于創建物件 - 使用
factory-method進行實體化- 使用實體工廠實體化
- 使用靜態工廠實體化
- 使用構造器反射進行實體化
- 使用
SmartInstantiationAwareBeanPostProcessor決議構造器,然后反射實體化 - 使用無參構造器進行實體化
- 使用
在屬性填充populateBean時大致可以分為4個步驟:
- 呼叫
InstantiationAwareBeanPostProcessor介面的after方法修改Bean的資訊 - 自動裝配,將決議的屬性和屬性值放入到
pvs變數中- 按
autowireByType自動裝配 - 按
autowireByName自動裝配
- 按
- 執行通過
CommonAnnotationBeanPostProcessor和AtowiredAnnotationBeanPostProcessor決議的注解,然后注入到欄位上 - 對屬性的值進行決議,決議
pvs, 會涉及到引數轉換,spel運算式決議,參考型別,String型別,List型別,Map型別,Set型別,Properties型別的決議,屬性編輯器的決議等,
接下來解讀初始化階段
bean的初始化
bean的初始化initializeBean方法,直接上原始碼:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 執行Aware 方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 執行 BeanPostProcessor before 介面
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 執行 init-method 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 執行BeanPostProcessor after 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
原始碼邏輯也很簡單,大概就分成了4步:
- 執行
Aware介面的方法invokeAwareMethods - 執行
BeanPostProcessor#postProcessBeforeInitialization - 執行初始化方法
- 執行
BeanPostProcessor#postProcessAfterInitialization
執行Aware介面的方法
點進去:
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// 執行BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// 執行BeanClassLoaderAware
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// 執行BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
這里只執行了3個介面的方法,BeanNameAware,BeanClassLoaderAwre,BeanFactoryAware,在Spring容器中不止這些Aware介面,這里為什么只執行了三個Aware介面?
在Spring容器BeanFactory構造時,對這三個介面進行了忽略:
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
所以這里只執行了這三個Aware介面,這里忽略,實際上就是不然這些屬性通過自動裝配設定屬性值,而是通過Spring自己的回呼進行設定值,
另外我們在開始的準備BeanFactory的時候又進行了忽略Aware介面:
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
這6個介面在哪里執行的呢?在BeanFactory準備階段注冊了一個BeanPostProcessor的實作叫ApplicationContextAwareProcessor類,這個類的before方法中就進行了呼叫:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
// 執行Aware介面
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
為什么要分開處理呢?
個人認為主要是做了個區分而已,前面三個介面輸入BeanFactory范疇,而這6個介面屬于ApplicationContext范疇,只是進行了歸類處理而已,
執行BPP的Before方法
代碼比較簡單,就是回圈的執行了BPP的before介面,這里在執行的時候,實作上也執行了在Bean進行merge的時候決議的@PostConstruct注解,
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = https://www.cnblogs.com/redwinter/p/findLifecycleMetadata(bean.getClass());
try {
// 執行初始化方法
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName,"Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
這個方法的實作類為InitDestroyAnnotationBeanPostProcessor
執行初始化方法
執行初始化方法的時候,會分為兩步,一個是執行InitializingBean 的afterPropertiesSet方法,另一個是執行自定義的init-method方法
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 判斷當前Bean是否是實作了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 + "'");
}
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);
}
}
}
執行BPP的after介面
BPP的after主要是用來實作AOP的,所以這里簡單介紹下,回圈執行after方法的呼叫,
原始碼:
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;
}
原始碼比較簡單,就回圈執行了方法的呼叫,
初始化就解讀完了,Spring的Bean的創建也基本講完,最終創建出來的Bean物件就會放入到一級快取singletonObjects中,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/479219.html
標籤:Java
