IoC容器加载流程

IoC容器加载流程

流程主要分为两个阶段:

  1. Bean的配置解析阶段:将Bean的配置信息转换成BeanDefinition
  2. Bean的创建阶段:根据BeanDefinition进行Bean创建

1. 加载流程

1.1 配置解析

加载流程:

  1. 资源文件定位:一般是在ApplicationContext的实现类里完成的,ResourceLoader接口的getResource()方法,可以将外部的资源,读取为Resource类
  2. 加载配置文件:通过BeanDefinitionReader读取配置文件或配置类
  3. 注解扫描:根据ComonentScan注解的路径进行扫描,未指明时会从声明这个注解的配置类所在包以及其子包进行扫描,读取@Bean、@Component、@Service等Bean声明注解
  4. 解析注册BeanDefinition:针对扫描出来的bean信息进行解析,生成的对象注册到BeanDefinitionRegistry中(BeanDefinitionRegistry是一个接口,提供了向IoC容器中注册BeanDefinition的方法)

1.2 Bean创建

IoC容器中的bean默认为延迟加载只有在需要使用时才会被实例化。这个过程是通过Bean的getBean方法实现的。

创建流程

  1. 配置读取:根据Bean的名称或类型查找BeanDefinition;
  2. Bean实例化:容器根据BeanDefinition中的定义,调用Bean工厂实例化Bean对象。可以通过构造函数实例化、工厂方法实例化、静态工厂方法实例化等方式来创建Bean对象;
  3. Bean属性注入:通过BeanPostProcessor接口中的postProcessPropertyValues方法来对Bean的属性进行填充。这个过程是通过PropertyValues封装Bean的属性,然后使用依赖注入技术自动填充。这过程可以为构造注入或者设值注入;
  4. 处理依赖关系:容器会处理Bean之间的依赖关系,将依赖的Bean注入到需要的地方 ;
  5. 执行初始化方法:容器会调用Bean的初始化方法,可以通过实现InitializingBean接口或在配置文件中指定初始化方法来定义Bean的初始化逻辑。
  6. 注册Bean:容器会将实例化、属性设置和初始化完成的Bean对象注册到容器中,以便后续的使用和管理。

2. BeanDefinition

BeanDefinition 描述和定义Spring容器中Bean的元数据对象。

其中包含了许多属性,如 Bean 的名称、类型、作用域、构造函数参数、属性等等。

BeanDefinition 还可以设置生命周期回调方法,用于在 Bean 的生命周期中执行一些初始化或销毁操作。

这些可以通过 XML 配置、注解、Java 配置等方式进行配置:

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 定义一个bean,其中class属性指定了类的全限定名,id属性是该bean的唯一标识 -->
    <bean id="myBean" class="com.bean.DemoBean" >
        <!-- 这里可以配置构造函数参数、属性setter方法参数等 -->
    </bean>

</beans>

注解定义

import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;

@Getter
@Setter
@Component
public class DemoBeanA {

    private String name;

}

@Configuration + @Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DemoBean {

    @Bean("demoBeanA1")
    public DemoBeanA demoBeanA() {
        // 自定义装配 一般用于将第三方类库装配为bean 或者 需要自行设定一些参数的bean
        DemoBeanA demoBeanA = new DemoBeanA();
        demoBeanA.setName("demoBeanA");
        return demoBeanA;
    }

}

代码注册

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@Slf4j
public class DemoBeanRegister {

    static AnnotationConfigApplicationContext applicationContext = 
            new AnnotationConfigApplicationContext(DemoBean.class);
    
    public static void main(String[] args) {
        beanRegister(DemoBeanA.class);
        DemoBeanA demoBeanA = applicationContext.getBean(DemoBeanA.class);
        log.debug(demoBeanA.getName());
    }

    public static void beanRegister(Class<?> beanClass) {
        applicationContext.register(beanClass);
        applicationContext.refresh();
    }

}

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值