Spring Bean实例化:从源码窥探生命之源

1. 引言

在Spring框架中,Bean的生命周期是一个至关重要的概念,它涉及了Bean的创建、初始化、使用以及销毁等多个阶段。其中,Bean的实例化作为生命周期的起点,具有举足轻重的地位。以下将对Spring中Bean的实例化过程进行深度解析,结合源码分析,提供更深入的理解。


2. Bean实例化的背景与意义

在Spring的IOC(Inversion of Control,控制反转)容器中,Bean的实例化是容器管理Bean生命周期的第一步。通过实例化,Spring容器能够创建出开发者定义的Bean对象,为后续的依赖注入、初始化等操作奠定基础。因此,对Bean实例化过程的理解,是掌握Spring框架核心机制的关键。


3. Bean实例化的源码分析

  1. 扫描与解析
    • Spring启动时,会根据配置的包路径进行扫描,获取指定路径下的所有类文件。
    • 利用MetadataReaderFactory解析类文件,得到MetadataReader对象,该对象包含了类的元数据信息。
    • 通过excludeFiltersincludeFilters以及条件注解@Conditional的筛选,确定哪些类需要被Spring容器管理。
  2. BeanDefinition的创建
    • BeanDefinition是Spring框架中描述Bean的元数据信息的接口,具体实现类有RootBeanDefinition等。
    • Spring会读取配置文件或注解中的类名、作用域、属性等信息,并设置到BeanDefinition对象中。
  3. 实例化过程
    • Spring通过AbstractBeanFactorydoGetBean方法获取Bean实例。
    • 如果Bean是单例(isSingleton()true),则首先尝试从缓存中获取实例。
    • 如果缓存中没有,则调用getSingleton方法中的lambda表达式,通过createBean方法创建Bean实例。
      • createBean方法内部调用doCreateBean方法,该方法又调用instantiateBean方法实际创建Bean实例。
      • instantiateBean方法使用反射机制调用类的构造函数创建Bean实例。
    • 如果Bean是原型(prototype)或其他非单例类型,则每次调用getBean时都会重新创建实例。

以下是简化的源码片段:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {  
    // 实例化Bean之前的前置处理  
    // ...  
  
    // Instantiate the bean.  
    BeanWrapper instanceWrapper = null;  
    if (mbd.isSingleton()) {  
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
    }  
    if (instanceWrapper == null) {  
        // 使用指定的构造函数或默认构造函数实例化Bean  
        instanceWrapper = createBeanInstance(beanName, mbd, args);  
    }  
  
    // ... 依赖注入、初始化等后续步骤 ...  
  
    return instanceWrapper.getWrappedInstance();  
}  
  
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {  
    // ... 省略了部分逻辑 ...  
  
    // 确定实例化策略:通过构造函数、工厂方法等  
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);  
    if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||  
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {  
        return autowireConstructor(beanName, mbd, ctors, args);  
    }  
  
    // 默认使用无参构造函数实例化  
    return instantiateBean(beanName, mbd);  
}  
  
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {  
    try {  
        Object beanInstance;  
        final BeanFactory parent = this;  
        if (System.getSecurityManager() != null) {  
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->   
                getInstantiationStrategy().instantiate(mbd, beanName, parent),  
                getAccessControlContext());  
        } else {  
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);  
            // ... 省略了部分逻辑 ...  
        }  
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);  
        initBeanWrapper(bw);  
        return bw;  
    } catch (Throwable ex) {  
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);  
    }  
}
  1. 依赖注入
    • 在Bean实例创建后,Spring会根据BeanDefinition中配置的依赖关系,通过populateBean方法进行依赖注入。
    • 依赖注入可以通过属性注入、构造函数注入等方式实现。
  2. Bean后处理器
    • 如果存在Bean后处理器(BeanPostProcessor),则Spring会在Bean实例化之后、初始化之前调用Bean后处理器的postProcessBeforeInitialization方法。
    • 在Bean初始化之后,Spring还会调用Bean后处理器的postProcessAfterInitialization方法。

4. 总结

Spring中Bean的实例化过程涉及扫描、解析、创建BeanDefinition、实例化Bean、依赖注入以及Bean后处理器等多个步骤。这些步骤共同确保了Bean的正确创建和初始化,为Spring框架的IOC容器提供了坚实的基础。通过深入解析这些步骤的源码,能够更好地理解Spring框架的工作原理,从而在实际开发中更好地运用它。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BrightChen666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值