Spring5.0源码学习系列之核心技术IoC概述(三)

235 阅读7分钟

Spring5.0源码学习系列之核心技术IoC概述(三)


提示:Spring官网对Spring的主要技术做了比较详细的介绍,详情参考Spring官网spring core文档,IOC实现是springframework的一个核心功能,本博客对spring ioc进行比较大概的描述,仅作为学习源码之前的科普

@TOC


前言

提示:Spring框架源码是java领域比较好的源码,原因是这款框架架构设计很好,框架拓展性灵活,这就是spring框架流行的原因之一。而Ioc(控制反转)模块和aop是springframework的两个核心功能。ioc和aop是一种技术思想,早在springframework框架开发之前就已经提出来了,不过更偏向于理论,而spring在技术层面对这两个思想做了很好的实现(java领域)


提示:以下是本篇文章正文内容,下面案例可供参考,仅作为学习ioc实现源码之前的科普,因为ioc源码比较复杂,学习源码之前要一些必要的了解,首先应用都不熟悉,看源码肯定是看不懂的,所以要先通过学习了解熟悉spring的ioc实现

一、IOC是什么?

IOC:Inversion of controll(控制反转 / 反转控制),ioc是一种技术思想,在spring框架开发之前就已经提出来的,spring框架对ioc技术思想进行了很好的实现

对控制反转的理解:控制反转(IOC)可以理解为获取依赖对象的方式反转过来,有反转就有“正转”,所谓“正转”可以这样理解,“正转”就是常规的获取对象方式,比如类A依赖于类B,在类A中要获取类B,就是new一个B对象既可,这种就是“正转“,这种方法对依赖对象的管理获取,或者说是由类A去触发的。而反转的情况是对依赖对象的控制都交给spring ioc容器,对象的创建管理都给ioc容器,需要什么对象,直接通过ioc容器拿既可

不依赖于IOC的情况:直接通过new获取依赖对象 在这里插入图片描述 有Spring IOC容器的情况:所有对象的创建管理都给spring ioc容器控制,需要什么对象直接找ioc容器拿,如图: 在这里插入图片描述 为什么叫控制反转?

  • 控制:指的是对依赖对象控制,实例,管理
  • 反转:对依赖对象的控制交给外部环境,也即Spring IOC容器

二、IOC容器的作用

引用其它博客对ioc解的诠释:www.52codes.net/article/401…,从图可以看出ioc容器其实就是用于解耦的,体现了oop思想 在这里插入图片描述

ps:没有IoC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中


三、IOC和DI区别

DI:Dependancy Injection(依赖注入),控制反转(IOC)和依赖注入(DI)其实描述的是同一件事,只不过是角度不同

  • 控制反转(IOC)站在对象角度,强调对象的控制交给(反转给)IOC容器,IOC容器控制对象的实例、管理
  • 依赖注入(DI)站在IOC容器的角度,说明的是IOC容器将依赖对象注入到IOC容器,假如类A声明了类B的属性,在ioc容器启动时候就需要将类B对象注入给类A

四、Spring容器概述

Spring官网找到IOC容器的相关说明文档,发现官方文档还是比较详细的,虽然没有对Spring框架源码进行分析,不过也对IOC进行了很详细的说明,详情可以参考官方文档,本博客参考官方文档进行摘要说明: 在这里插入图片描述

Spring官网对Spring ioc容器的描述:

This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1] principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.

其实意思也和前面说明的相近,也是说明控制反转(IOC)其实就是将依赖对象的控制反转给IOC容器

官网的图片,描述了spring容器管理对象的大概过程: 在这里插入图片描述


五、如何使用IOC容器?

也即官方文档说明的三个步骤: 在这里插入图片描述 翻译过来就是:

  • 配置元数据
  • 实例IOC容器
  • 使用IOC容器

ok,跟着官方文档,进行学习:

5.1、配置元数据

官网介绍了两种方式:也即基于注解的,另外一种是基于java配置在这里插入图片描述 基于注解的,主要是spring官方的提供的主键,比如经常用的@Autowired主键等等,详情可以参考官方文档 在这里插入图片描述

基于java配置的有两种方法,一种是写一个@Configuration配置类,一个是通过xml配置文件,详情可以参考官方文档

在这里插入图片描述

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}
<beans>
    <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>

用思维导图,简单画图: 在这里插入图片描述

5.2、实例IOC容器

实例一个Spring IOC容器,官网的例子是:

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- services -->

    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for services go here -->

</beans>

简单做下归纳:

在这里插入图片描述

5.3、使用IOC容器

实例好IOC容器之后,既可获取对应的依赖对象: 在这里插入图片描述


六、Spring Bean概述

6.1、Spring中的Bean概述

Bean概述:Spring中的Bean指Beandefinition,Beandefinition是经过Spring容器实例的一个实例

6.2、实例Bean的方式

在这里插入图片描述

在这里插入图片描述 官网代码示例:静态工厂实例

public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}

    public static ClientService createInstance() {
        return clientService;
    }
}

工厂实例:

public class DefaultServiceLocator {

    private static ClientService clientService = new ClientServiceImpl();

    public ClientService createClientServiceInstance() {
        return clientService;
    }
}

七、定义SpringBean

7.1、定义Spring Bean

Spring官网给出了如何定义一个Spring Bean: 在这里插入图片描述 本博客用思维导图做下归纳: 在这里插入图片描述

7.2、Bean作用域

在这里插入图片描述

范围描述
单例(Singleton)(默认)单例的beanDefinition
原型(prototype)多例,多个实例的beanDefinition
请求(request)单例的, 作用于HTTP 请求的生命周期
会话(session)单例的, 作用Http会话的声明周期
应用(application)单例的,应用于ServletContext生命周期
网络socket(webSocket)单例的,应用于Websocket环境

单例模式的图例,图来自Spring官网 在这里插入图片描述

原型模式,也称之为多例模式,图例来自Spring官网: 在这里插入图片描述

7.3、Bean懒加载模式

懒加载(Lazy-initialized beans):懒加载模式是bean在第一次调用时候被实例,而不是spring容器启动时候,默认是不开启的,( A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.),通过改配置lazy-init="true"


八、Spring生命周期

Spring的生命周期是Spring框架的一个比较重要的方面,不过内容比较多,所以本博客只是简单进行描述

在这里插入图片描述


九、Spring后置处理器

后置处理器是Spring框架的一个比较重要的方面,不过内容比较多,所以本博客只是简单进行描述 在这里插入图片描述


十、什么是循环依赖?

两个及以上的类互相调用依赖,形成闭环,Spring框架检测到这种场景会抛 BeanCurrentlyInCreationException,提前暴露对象的方法 在这里插入图片描述

在这里插入图片描述


归纳

提示:这里对文章进行总结: 例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

在这里插入图片描述