Spring源码阅读(一)Bean的创建过程

2025年4月16日 · 1927 字 · 4 分钟 · Spring

实例化 -> 属性填充 -> BeanPostProcessor前置处理 -> 初始化阶段 -> BeanPostProcessor后置处理 -> 初始化完成 -> PostConstruct -> InitializingBean.afterPropertiesSet -> 自定义init-method -> AOP

创建的大致流程

推断构造方法

利用该类的构造方法来实例化得到一个对象(但是如何一个类中有多个构造方法,Spring则会进行选择,这个叫做推断构造方法)

依赖注入

得到一个对象后,Spring会判断该对象中是否存在被@Autowired注解了的属性,把这些属性找出来并由Spring进行赋值(属性填充)

BeanPostProcessor处理和初始化

依赖注入后,Spring会判断该对象是否实现了BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口,如果实现了,就表示当前对象必须实现该接口中所定义的setBeanName()setBeanClassLoader()setBeanFactory()方法,那Spring就会调用这些方法并传入相应的参数(Aware回调)

PostConstruct 处理

Aware回调后,Spring会判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法(初始化前)

InitializingBean.afterPropertiesSet

紧接着,Spring会判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现该接口中的afterPropertiesSet()方法,那Spring就会调用当前对象中的afterPropertiesSet()方法(初始化)

自定义init-method

执行自定义init-method

AOP

最后,Spring会判断当前对象需不需要进行AOP,如果不需要那么Bean就创建完了,如果需要进行AOP,则会进行动态代理并生成一个代理对象做为Bean(初始化后)

我们可以发现,当Spring根据UserService类来创建一个Bean时:

  1. 如果不用进行AOP,那么Bean就是UserService类的构造方法所得到的对象。
  2. 如果需要进行AOP,那么Bean就是UserService的代理类所实例化得到的对象,而不是UserService本身所得到的对象。

Bean对象创建出来后:

  1. 如果当前Bean是单例Bean,那么会把该Bean对象存入一个Map<String, Object>,Map的key为beanName,value为Bean对象。这样下次getBean时就可以直接从Map中拿到对应的Bean对象了。(实际上,在Spring源码中,这个Map就是单例池)
  2. 如果当前Bean是原型Bean,那么后续没有其他动作,不会存入一个Map,下次getBean时会再次执行上述创建过程,得到一个新的Bean对象。

初始化入口

AbstractAutowireCapableBeanFactory

// 源码路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 调用Aware接口方法
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessor前置处理(包括@PostConstruct注入)
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 执行InitializingBean和init-method
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException();
    }

    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessor后置处理
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

@PostConstruct 处理机制

InitDestroyAnnotationBeanPostProcessor

// 源码关键路径:org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 获取@PostConstruct元数据
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 反射执行初始化方法
        metadata.invokeInitMethods(bean, beanName);
    }
    catch (Throwable ex) {
        throw new BeanCreationException();
    }
    return bean;
}

InitializingBean 处理机制

// 源码路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
        
    if (bean instanceof InitializingBean) {
        // 执行接口方法
        ((InitializingBean) bean).afterPropertiesSet();
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName)) {
            // 反射调用自定义init方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

执行顺序与线程安全

BeanPostProcessor.postProcessBeforeInitialization -> PostConstruct -> InitializingBean.afterPropertiesSet -> 自定义init-method -> BeanPostProcessor.postProcessAfterInitialization

核心类

  • InitDestroyAnnotationBeanPostProcessor

    • postProcessBeforeInitialization()
    • findLifecycleMetadata()
  • AbstractAutowireCapableBeanFactory

    • invokeInitMethods()
    • invokeCustomInitMethod()
  • CommonAnnotationBeanPostProcessor

    • postProcessBeforeInitialization()

@PostConstruct 和 InitializingBean

@PostConstruct 和 InitializingBean 在 Spring 生命周期中扮演着不同的角色:

@PostConstruct

  • 基于标准注解的轻量级初始化
  • 通过BeanPostProcessor实现
  • 支持方法级细粒度控制

InitializingBean

  • 框架原生接口方案
  • 直接集成到Bean初始化流程
  • 提供类型安全的回调

生产环境选择建议

  • 80%场景使用@PostConstruct
  • 需要强制初始化保障时选择InitializingBean
  • 第三方库集成使用init-method