Spring IOC与DI 深度剖析源码(一)

Spring IOC与DI 深度剖析源码(一)

我是一个有10年+Java开发老炮,很荣幸与大家分享个人对相关知识点的理解!
当我们谈论Spring框架时,不可避免地要提到其最重要的功能之一——控制反转(Inversion of Control,简称IOC)容器。Spring的IOC容器是一个轻量级的容器,它提供了一种管理Java Bean及其依赖关系的方式,让我们从繁琐的依赖关系管理中解脱出来,让我们的代码更加简洁,更易于维护。

在本文中,我将深入探讨Spring IOC,DI容器的核心概念和源码实现,并带您一步步解析Spring IOC,DI容器的实现细节。



一、Spring IOC核心概念

1. Bean

在Spring中,Bean是指由Spring容器管理的Java对象,通常是由IoC容器初始化、配置和管理的对象。Bean可以是任何Java对象,包括POJO(Plain Old Java Object,普通的Java对象)、组件、服务等;

2. IOC概念

在传统的编程中,我们通常需要手动创建和管理对象之间的依赖关系。这种方式容易导致代码的耦合度过高,且代码难以维护和扩展。IOC 是一种设计模式,它的核心思想是将对象的创建和依赖关系的管理从应用程序中抽离出来,交由容器来管理;

在 Spring 中,IOC 容器负责创建 Bean,管理 Bean 的生命周期,并将 Bean 注入到其他 Bean 中。通过将 Bean 的创建和依赖关系的管理交给 Spring 容器,我们可以实现代码的松耦合,便于测试、维护和扩展;

3. ApplicationContext

ApplicationContext是Spring框架中的核心接口之一,它是IoC容器的实现。ApplicationContext继承了BeanFactory接口,提供了更多的功能和特性。ApplicationContext可以读取XML文件、Java注解和Java代码中的元数据,通过反射和代理机制实现依赖注入,将对象的创建和管理交给Spring容器;

二、Spring DI核心概念

1. DI核心

DI 是 IOC 的一种实现方式,全称 Dependency Injection,即依赖注入。在 Spring 中,DI 是指将 Bean 的依赖关系自动注入到 Bean 中,而不需要手动编写代码来实现;

在 DI 中,我们需要定义 Bean 的依赖关系,然后将这些依赖关系交给 Spring 容器来管理。Spring 容器会自动创建 Bean,并将其注入到其他 Bean 中;

2. Bean的作用域

在Spring框架中,Bean的作用域指的是Bean实例的生命周期。Spring框架提供了五种常见的Bean作用域:singleton、prototype、request、session和global session。其中,singleton表示单例模式,每个Bean只会有一个实例;prototype表示原型模式,每次获取Bean都会创建一个新的实例;request表示每次HTTP请求都会创建一个新的实例;session表示每个HTTP会话都会创建一个新的实例;global session表示全局会话,只会在集群环境下使用;

3. DI实现原理

Spring的DI实现原理是通过反射机制来实现的。当容器初始化时,它会读取配置文件或注解信息,将Bean的依赖关系以及其他配置信息加载到容器中。然后,容器根据依赖关系创建Bean的实例,并将依赖的Bean注入到当前Bean中。当Bean的生命周期结束时,容器会自动调用Bean的销毁方法,释放资源;

概念搞清楚,接下来看看核心接口与类

三、Spring IOC和DI核心接口与类

1. BeanFactory接口

在Spring中,BeanFactory是IOC容器的核心接口之一。它定义了IoC容器的基本功能,如Bean的实例化、属性赋值、依赖注入、Bean的生命周期管理等。BeanFactory接口的实现类有:XmlBeanFactory、DefaultListableBeanFactory等;

2. BeanDefinition接口

BeanDefinition接口是Bean定义的抽象接口,它定义了Bean的基本属性,如类名、构造方法、属性等。BeanDefinition接口的实现类有:GenericBeanDefinition、RootBeanDefinition等;

3. BeanDefinitionReader接口

BeanDefinitionReader接口是用来读取Bean的定义信息的接口,它可以从XML文件、注解或Java代码中读取Bean的定义信息,并将其转化成BeanDefinition对象。BeanDefinitionReader接口的实现类有:XmlBeanDefinitionReader、AnnotationBeanDefinitionReader等;

4. DefaultListableBeanFactory接口

DefaultListableBeanFactory是Spring中默认的IoC容器实现类,它是BeanFactory接口的实现类之一。DefaultListableBeanFactory继承了AbstractAutowireCapableBeanFactory类,提供了Bean的注册、BeanDefinition的管理、Bean的实例化、属性赋值、依赖注入等基本功能;DefaultListableBeanFactory还提供了事件机制、Bean的作用域、AOP等高级功能;

5. AutowireCapableBeanFactory接口

AutowireCapableBeanFactory接口是BeanFactory接口的扩展接口,提供了更丰富的Bean实例化、属性赋值、依赖注入、生命周期管理等功能。AutowireCapableBeanFactory接口的实现类有:DefaultListableBeanFactory、AnnotationConfigApplicationContext等;

6. AbstractBeanFactory接口

AbstractBeanFactory是BeanFactory接口的抽象实现类,它封装了Bean的创建、依赖注入、属性赋值、生命周期管理等基本功能,并提供了容器初始化和BeanDefinition的加载、解析等功能;

三、Spring IOC和DI 实现过程

1. Bean的实例化

Bean的实例化是指容器根据BeanDefinition创建Bean的实例。Bean的实例化过程由BeanFactory接口的getBean方法完成。在DefaultListableBeanFactory类中,getBean方法的实现如下:

@Override
public Object getBean(String name) throws BeansException {
    // 获取BeanDefinition
    RootBeanDefinition bd = getMergedLocalBeanDefinition(name);
    // 创建Bean实例
    Object bean = createBean(name, bd, null);
    return bean;
}

在getBean方法中,首先根据Bean的名称获取BeanDefinition,然后调用createBean方法创建Bean的实例。在createBean方法中,会根据BeanDefinition创建Bean的实例,并完成依赖注入和属性赋值等操作。创建Bean实例的过程由AbstractAutowireCapableBeanFactory类的doCreateBean方法完成。doCreateBean方法的实现如下:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
    // 创建Bean实例
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    // 实例化Bean
    final Object bean = instanceWrapper.getWrappedInstance();
    // 属性赋值
    populateBean(beanName, mbd, instanceWrapper);
    // 初始化Bean
    initializeBean(beanName, bean, mbd);
    return bean;
}

在doCreateBean方法中,首先调用createBeanInstance方法创建Bean的实例。createBeanInstance方法会根据BeanDefinition创建Bean的实例,并完成构造方法的调用。然后,调用populateBean方法完成属性的赋值和依赖注入。最后,调用initializeBean方法完成Bean的初始化;

2. Bean的属性赋值和依赖注入

属性赋值和依赖注入是指将Bean的属性值和依赖的Bean注入到当前Bean中。在Spring中,属性赋值和依赖注入由AbstractAutowireCapableBeanFactory类的populateBean方法完成。populateBean方法的实现如下:

protected void populateBean(final String beanName, final RootBeanDefinition mbd, final BeanWrapper bw) {
    PropertyValues pvs = mbd.getPropertyValues();
    if (!pvs.isEmpty()) {
        MutablePropertyValues mpvs = null;
        List<PropertyValue> original;

        synchronized (mergedBeanDefinitions) {
            original = this.mergedBeanDefinitions.remove(beanName

在populateBean方法中,首先获取Bean的属性值。如果Bean的属性值不为空,就创建MutablePropertyValues对象,并将属性值添加到MutablePropertyValues中。然后,遍历Bean的属性,将依赖的Bean注入到当前Bean中。依赖注入的过程由AutowiredAnnotationBeanPostProcessor类的postProcessPropertyValues方法完成;postProcessPropertyValues方法的实现如下:

@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        metadata.inject(bean, beanName, pvs);
    } catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    return pvs;
}

在postProcessPropertyValues方法中,首先根据Bean的名称、类型和属性值获取InjectionMetadata对象,然后调用InjectionMetadata的inject方法进行依赖注入。在inject方法中,首先获取Bean的实例,然后遍历Bean的属性,将依赖的Bean注入到当前Bean中;

3. Bean的销毁

Bean的销毁是指释放Bean占用的资源。在Spring中,Bean的销毁由DisposableBean接口和@PreDestroy注解完成。当容器关闭时,会调用实现了DisposableBean接口的Bean的destroy方法和使用了@PreDestroy注解的方法。在DefaultSingletonBeanRegistry类中,实现了DisposableBean接口和使用了@PreDestroy注解的Bean会被添加到一个销毁的Bean列表中。在容器关闭时,会依次调用销毁的Bean的destroy;

1. 初始化容器流程

三、Spring IOC和DI 设计模式

提示:Spring IOC和DI容器是基于反转控制(Inversion of Control)和依赖注入(Dependency Injection)的设计模式实现的。

Spring IOC和DI容器还使用了其他设计模式,包括:

1.工厂模式(Factory Pattern):Spring IOC容器中的BeanFactory就是一个工厂模式的实现,用于创建和管理Bean对象。
2.单例模式(Singleton Pattern):Spring IOC容器中的Bean默认是单例的,可以在容器中创建一个对象实例,并在整个应用程序中共享该实例。
3.原型模式(Prototype Pattern):Spring IOC容器中的Bean也可以配置为原型作用域,每次获取Bean都会创建一个新的实例。
4.代理模式(Proxy Pattern):Spring AOP(面向切面编程)功能是基于代理模式实现的,通过代理对象来实现对目标对象的增强。
总之,Spring IOC和DI容器的实现离不开许多常见的设计模式,这些模式在代码的设计和实现中都有着非常重要的作用


总结

提示:后续会深入讲解设计模式:

例Spring的IOC和DI容器是Spring框架的核心部分,它可以将Bean的创建、初始化、依赖注入和销毁等工作自动化。在Spring的IOC和DI容器中,Bean的创建过程由BeanFactory和ApplicationContext完成。Bean的创建过程主要包括Bean的实例化、Bean的属性赋值和Bean的初始化。Bean的销毁由DisposableBean接口和@PreDestroy注解完成。通过深度剖析Spring的IOC和DI容器源码,可以更深入地理解Spring框架的核心机制,从而更好地使用Spring框架。

以上希望可以帮助到你,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值