spring ioc加载流程

本文详细介绍了Spring框架中Bean的加载流程,包括总框架加载流程、XML方式加载流程及注解扫描加载流程。深入探讨了从applicationContext创建beanFactory开始,直至完成BEAN实例化的全过程。

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

一、总框架加载流程

     1.applicationContext创建beanFactory->

     2.beanFactory通过XMLbeandefineReader解析文件,获取BeanDefinition,并注册到beanfactory中。这时只是把定义放到工厂,并没有真正生成实例。

     3.中间会调用beanfactoryPostProcesser的BEAN,在这种可以自定义加载扩展BEAN的流程。

     4.finishBeanFactoryInitialization对所有非延迟加载的单例BEAN进行实例化,此时会创建对象,然后会先调用beanPostProcesser的before接口,插入属性, 然后注入属性到对象中,后面调用beanPostProcesser的after接口修改属性。通过beanWrapperImpl.

二、XML方式加载流程。

    1.使用ClassPathXmlApplicationContext加载BEAN创建的XML文件。

ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring1.xml");
PeopleBean peopleBean = (PeopleBean) classPathXmlApplicationContext.getBean("people1");
System.out.println(" name: "+ peopleBean.getName());
IPeopleService peopleService  = (IPeopleService) classPathXmlApplicationContext.getBean("peopleService");

三、通过注解扫描加载流程。

    1.使用ClassPathXmlApplicationContext加载BEAN创建的XML文件。

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!--使用context命名空间,通知spring扫描指定目录,进行注解的解析-->
    <context:component-scan base-package="com.tpw.newday.service.people"/>

    <bean id="people1" class="com.tpw.newday.bean.PeopleBean">
        <property name="name" value="zhangsan"/>
    </bean>

    <bean id="people2" class="com.tpw.newday.bean.PeopleBean">
        <property name="name" value="lisi"/>
    </bean>

    <bean id="people3" class="com.tpw.newday.bean.PeopleBean">
        <property name="name" value="wangwu"/>
    </bean>

    <bean id="peopleConfig" class="com.tpw.newday.config.PeopleConf">
    </bean>

    <bean id="peopleService" class="com.tpw.newday.service.people.PeopleServiceImpl">
        <property name="peopleBean1" ref="people1"/>
        <property name="peopleBean2" ref="people2"/>
    </bean>

</beans>

    

PeopleServiceImpl源码:

package com.tpw.newday.service.people;

import cn.hutool.json.JSONUtil;
import com.tpw.newday.bean.PeopleBean;
import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

import javax.annotation.Resource;

/**
 * <h3>newday</h3>
 * <p></p>
 *
 * @author : lipengyao
 * @date : 2021-06-25 09:53:24
 **/

@Data
public class PeopleServiceImpl implements  IPeopleService,InitializingBean,BeanNameAware,BeanClassLoaderAware
,BeanFactoryAware{

    private PeopleBean peopleBean1;

    private PeopleBean peopleBean2;

    @Resource(name = "people3")
    private PeopleBean peopleBean3;

    @Override
    public void save(PeopleBean peopleBean) {
        System.out.println("PeopleServiceImpl--> save peopleBean:" + JSONUtil.toJsonStr(peopleBean));
    }

    @Override
    public PeopleBean getPeople(int index) {
        PeopleBean peopleBean = null;
        switch (index){
            case 1:
                peopleBean = peopleBean1;
                break;
            case 2:
                peopleBean = peopleBean2;
                break;
            case 3:
                peopleBean = peopleBean3;
                break;
        }
        System.out.println("PeopleServiceImpl--> getPeople peopleBean:" + JSONUtil.toJsonStr(peopleBean));
        return peopleBean;
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("PeopleServiceImpl--> afterPropertiesSet PeopleServiceImpl:" );
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println(" PeopleServiceImpl-->setBeanClassLoader name:" +  classLoader.getClass().getName());
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        PeopleBean peopleBeanxx = (PeopleBean) beanFactory.getBean("people1");
        System.out.println(" PeopleServiceImpl-->setBeanFactory name:" +  peopleBeanxx.getName());
    }

    @Override
    public void setBeanName(String name) {
        System.out.println(" PeopleServiceImpl--> setBeanName name:" + name );
    }
}

2.spring的XML解析器解析component-scan标签时,会触发composerScanParser,此类为自动扫描指定包下的component注解类到beanfactory,然后再注入configPostProcesser,

AutowiredAnnotationBeanPostProcessor,
CommonAnnotationBeanPostProcessor,

 internalEventListenerProcessor,

internalEventListenerFactory,

internalPersistenceAnnotationProcessor,

3.在每个BEAN实例化后,会首先调用系统中MergedBeanDefinitionPostProcessor所有接口的

postProcessMergedBeanDefinition,

CommonAnnotationBeanPostProcessor类就会在这个实现中查找当前类所有带有resource注解的属性和方法,并且保存到InjectionMetadata中。并将属性设置到BeanFactory的externPropertiesmap中,AutowiredAnnotationBeanPostProcessor则是查找带有autowired,注解的属性和方法,原理一样。

4.在填充对象属性时populateBean函数会调用所有实现

InstantiationAwareBeanPostProcessor接口的对象的postProcessProperties方法,将上面保存的属性通过反射设置到对象属性中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值