Spring的bean实例化过程

本文深入探讨了Spring框架中bean的实例化过程,以XmlBeanFactory为例,从配置文件加载到bean的创建,详细解释了AbstractBeanFactory的doGetBean方法、AbstractAutowireCapableBeanFactory的实例化逻辑,包括Class的加载、BeanDefinition的解析以及最终通过反射进行的bean实例化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以XmlBeanFactory为例,最简单的取bean方式是:

BeanFactory factory = new XmlBeanFactory(new FileSystemResource("D:\\workspace\\JavaApplication2\\src\\javaapplication2\\spring\\beans.xml"));  
            Car obj = (Car)factory.getBean("car");  

Bean的配置文件内容也很简单:

<bean id="vehicle"   abstract="true">  
    <property name="wheel" value="Four wheeler"/>          
</bean>  
<bean id="car" class="javaapplication2.spring.Car" parent="vehicle">  
    <property name="dicky" value="Flat dicky"/>      
</bean>  

先看起始点,载入先走AbstractBeanFactory

public Object getBean(String name) throws BeansException {  
    return doGetBean(name, null, null, false);  
}  

doGetBean方法中:

// Create bean instance.  
if (mbd.isSingleton()) {  
         //传入一个内联类ObjectFactory并实现了getObject方法。  
         sharedInstance = getSingleton(beanName, new ObjectFactory() {  
    public Object getObject() throws BeansException {  
    try {  
        return createBean(beanName, mbd, args);  
    }  
    catch (BeansException ex) {  
    // Explicitly remove instance from singleton cache: It might have been put there  
    // eagerly by the creation process, to allow for circular reference resolution.  
    // Also remove any beans that received a temporary reference to the bean.  
    destroySingleton(beanName); //有异常则销毁bean  
            throw ex;  
    }  
}  
});  
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
        //此处开始实例化bean  

通过new ObjectFactory()的回调方法,回调当前类继承的createBean方法,该方法在父类AbstractAutowireCapableBeanFactory中:

AbstractAutowireCapableBeanFactory->

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  
            throws BeanCreationException {  
  
        // Make sure bean class is actually resolved at this point.  
        resolveBeanClass(mbd, beanName);  //载入该bean的class,并放置到mbd里面,bean的生成不在这里。  
  
        // Prepare method overrides.  
        try {  
            mbd.prepareMethodOverrides();  
        }  
        catch (BeanDefinitionValidationException ex) {  
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(),  
                    beanName, "Validation of method overrides failed", ex);  
        }  
  
        try {  
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  
            Object bean = resolveBeforeInstantiation(beanName, mbd);  //尝试获取一个proxy,普通bean这里一般是空的返回  
              
            if (bean != null) {  
                return bean;  
            }  
        }  
        catch (Throwable ex) {  
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
                    "BeanPostProcessor before instantiation of bean failed", ex);  
        }  
  
        Object beanInstance = doCreateBean(beanName, mbd, args);  //开始create bean的实例,mbd中包括了需要的class  
        if (logger.isDebugEnabled()) {  
            logger.debug("Finished creating instance of bean '" + beanName + "'");  
        }  
        return beanInstance;  
    }  

进入AbstractBeanFactory中的protected Class resolveBeanClass方法:

try {  
    if (mbd.hasBeanClass()) {  
        return mbd.getBeanClass();  
    }  
    if (System.getSecurityManager() != null) {  
        return AccessController.doPrivileged(new PrivilegedExceptionAction<Class>() {  
            public Class run() throws Exception {  
                return doResolveBeanClass(mbd, typesToMatch);  
            }  
        }, getAccessControlContext());  
    }  
    else {  
        return doResolveBeanClass(mbd, typesToMatch);   <---还要继续进去看生成方法。  
    }  
}  

转入doResolveBeanClass:

private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException {  
    if (!ObjectUtils.isEmpty(typesToMatch)) {  
        ClassLoader tempClassLoader = getTempClassLoader();  
        if (tempClassLoader != null) {  
            if (tempClassLoader instanceof DecoratingClassLoader) {  
                DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;  
            for (Class<?> typeToMatch : typesToMatch) {  
                dcl.excludeClass(typeToMatch.getName())  
            }  
        }  
        String className = mbd.getBeanClassName();  
        return (className != null ? ClassUtils.forName(className, tempClassLoader) : null); //通过自己的ClassUtils的forName方法来实例化class  
        }  
    }  
    return mbd.resolveBeanClass(getBeanClassLoader());  <----这里传入了bean的classloader,下面继续看这里  
}  

AbstractBeanDefinition->resolveBeanClass

public Class resolveBeanClass(ClassLoader classLoader) throws ClassNotFoundException {  
        String className = getBeanClassName();  
        if (className == null) {  
            return null;  
        }  
        Class resolvedClass = ClassUtils.forName(className, classLoader);//classloader传入后,仍然是用forName方法加载class  
        this.beanClass = resolvedClass;  
        return resolvedClass;  
    }  

再来看forName做了些什么

ClassUtils ->

ClassLoader classLoaderToUse = classLoader;  
if (classLoaderToUse == null) {  
    classLoaderToUse = getDefaultClassLoader();  
}  
try {  
    return classLoaderToUse.loadClass(name); //也比较简单,直接调用loadClass方法加载  
}  

最终将class load进来。

进入

AbstractAutowireCapableBeanFactory->instantiateBean

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd)  
...这里省略没用的        
    else {  
        beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);//下面看这里的实例化  
    }         
              
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);   //返回一个包装类对象  
    initBeanWrapper(bw);  
    return bw;  

SimpleInstantiationStrategy->instantiate

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner)  
    synchronized (beanDefinition.constructorArgumentLock) {  
            constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;  
        ...  
    }  
    return BeanUtils.instantiateClass(constructorToUse);     //BeanUtils来初始化实例 ,给出了实例化需要的构造函数  

再来看BeanUtils的实例化方法,比较简单,直接用反射的构造函数来newInstance。

BeanUtils->

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {  
    try {  
        ReflectionUtils.makeAccessible(ctor);  
        return ctor.newInstance(args);  
    }  

AbstractAutowireCapableBeanFactory->

Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)   
  
    // Initialize the bean instance.  
        Object exposedObject = bean;  
        try {  
            populateBean(beanName, mbd, instanceWrapper);  
            if (exposedObject != null) {  
                exposedObject = initializeBean(beanName, exposedObject, mbd);  
            }  
        }  
    return exposedObject;       //返回给AbstractBeanFactory  
### Spring Boot 中 Bean实例化过程与生命周期阶段 Spring 容器中的 Bean 生命周期可以分为多个阶段,这些阶段贯穿于 Bean 的创建、初始化以及销毁过程中。以下是关于 Spring Boot 中 Bean 实例化的详细解析: #### 1. **Bean 注册** 当 `ApplicationContext` 启动时,会读取配置文件或注解中的 Bean 定义,并将其注册到容器中。这一过程通常发生在 `refresh()` 方法调用期间[^3]。 ```java // 配置类或者 XML 文件中的 Bean 定义会被扫描并注册 @Configuration public class AppConfig { @Bean public MyService myService() { return new MyService(); } } ``` #### 2. **实例化 (Instantiation)** 在 Bean 被注册之后,Spring 开始对其进行实例化操作。这是通过反射机制完成的,具体逻辑位于 `AbstractAutowireCapableBeanFactory.doCreateBean()` 方法中。 - 如果存在工厂方法,则优先使用工厂方法进行实例化。 - 若无工厂方法,则直接通过构造函数实例化对象。 #### 3. **属性注入 (Populate Properties)** 一旦 Bean 成功被实例化Spring 将根据依赖关系向该 Bean 注入相应的属性值。此步骤同样由 `doCreateBean()` 方法负责执行[^4]。 ```java @Service public class UserService { private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } } ``` #### 4. **应用后处理器 (Apply Post Processors)** 在此阶段,Spring 提供了两个重要的扩展点——`BeanPostProcessor` 和 `BeanFactoryPostProcessor`,它们分别用于处理单个 Bean 或者整个 Bean 工厂[^1]。 - **BeanFactoryPostProcessor**: 修改 BeanDefinition 属性,在 Bean 初始化之前生效。 - **BeanPostProcessor**: 对已创建好的 Bean 进行额外加工,比如代理生成等。 #### 5. **初始化回调 (Initialization Callbacks)** 如果某个 Bean 实现了特定接口(如 `InitializingBean`),那么其对应的 `afterPropertiesSet()` 方法会在本阶段被执行;另外也可以通过 `<bean>` 元素上的 `init-method` 属性指定自定义初始化方法[^2]。 ```java @PostConstruct public void init() { System.out.println("Bean has been initialized."); } ``` #### 6. **可用状态 (Ready to Use)** 经过上述所有准备工序后,此时 Bean 即可投入使用。它可能作为其他组件的一部分参与到业务逻辑当中去。 #### 7. **销毁前清理工作 (Destruction Cleanup)** 对于具有有限作用域(例如 prototype)或者是显式关闭的应用上下文而言,最终还需要释放资源。这一步骤可通过实现 `DisposableBean` 接口或是设置 `destroy-method` 来达成目标。 --- ### 总结 综上所述,Spring Boot 下的 Bean 生命周经历了一系列精心设计的过程,从最基础的对象构建到最后的服务终止都得到了良好的支持。开发者能够利用各种钩子来自由操控这个流程以满足实际需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值