Spring 源码(17)Spring Bean的创建过程(8)Bean的初始化

知识回顾

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 = 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
中。

标签: Java

添加新评论