网站Logo 苏叶的belog

Spring核心概念

wdadwa
3
2026-03-30

一,Spring介绍

Spring 家族主要框架:

2953321-20250505085947511-610452282.png

上述三套构成了当先互联网 java 后端开发的百分之九十的技术框架。

  • Spring Cloud:这是一个微服务框架,旨在简化分布式系统的开发。它提供了一系列工具,用于处理诸如服务发现、配置管理、负载均衡、断路器、路由、微代理、事件驱动数据以及分布式消息传递等问题。Spring Cloud 构建在 Spring Boot 之上,利用 Spring Boot 的简化配置能力,使得开发和部署微服务变得更加容易。

  • Spring Framework:这是一个功能强大的全方位 Java 应用程序开发框架。Spring Framework 不仅限于单体应用,它也可以用于构建微服务和企业级应用。它提供了全面的基础设施支持,包括依赖注入(DI)、面向方面编程(AOP)、数据访问、事务管理、Web 应用程序开发等。

  • Spring Boot:这是一个基于 Spring Framework 的项目,旨在简化 Spring 应用的创建和配置。Spring Boot 通过自动配置和“开箱即用”的默认值,减少了开发人员配置应用的繁琐过程。它适用于构建独立、生产级的 Spring 应用,无需复杂的 XML 配置。

Spring 的发展史:

2953321-20250505085947304-419050155.png

二,Spring系统架构图

2953321-20250505085947491-1438436966.png

三,IoC与DI概念

在我们没使用 Spring 框架之前,我们调用其他类里面的方法都是通过new对象来创建的,但是这样会让代码之间的耦合度变高,当我们 new 的对象的那个类需要进行切换时,成本较高,需要重新编译,故通过 IOC 的方式来实现类之间的解耦。

  • IoC(Inversion of Control)控制反转

    • 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
  • Spring 技术对 Ioc 思想进行了实现:

    • Spring提供了一个容器,叫IoC容器,用来充当Ioc思想中的“外部
    • IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
  • DI(Dependency Injection)依赖注入

    • 在容器中建立 bean 与 bean 之间的依赖关系的整个过程,称为依赖注入
      2953321-20240625171301682-1843174317.png

    内聚:软件中各个功能模块内部的功能联系。
    耦合:衡量软件中各个层 / 模块之间的依赖、关联的程度。
    软件设计原则:高内聚低耦合

    使用 IoC 和 DI 的目标:充分解耦

    • 使用 IoC 容器管理 bean(IoC)

    • 在 IoC 容器内将有依赖关系的 bean 进行关系绑定 (DI)

    最终效果:使用对象时不仅可以直接从 IoC 容器中获取,并且获取到的 bean 已经绑定了所有的依赖关系

四,IoC与DI(XML版)

4.1 Ioc

:xml 版是 Ioc 和 DI 的早期使用方式,实际开发中我们是通过注解版来实现 Ioc 和 DI 开发的

  1. 导入 Spring 坐标

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    
  2. 2953321-20240625195030397-1230663242.png

  3. 2953321-20240625195057530-274160929.png

    注意:

    • bean的id不能重复
    • bean标签表示配置bean
    • id属性标示给bean起名字
    • class属性表示给bean定义类型(就是这个bean的位置)
  4. 2953321-20240625195122797-1322201939.png

4.2 DI

  1. 2953321-20240625200058250-1290330018.png

  2. 2953321-20240625200111636-1311312015.png
    还需要提供无参构造函数

  3. 2953321-20240625200133641-393405390.png

    注:

    • property标签表示配置当前bean的属性
    • name属性表示配置哪一个具体的属性
    • ref属性表示参照哪一个bean

五,Bean配置

5.1 Bean基础配置

2953321-20240625200854536-2043064510.png

5.2 Bean别名配置

在 xml 配置文件中,我们可给 Bean 起别名如下所示:

    <!--通过name属性来起别名,并且可以同时起多个别名,多个别命用逗号分隔-->
    <bean id="iocService" name="service,service2,service3" class="IocDemo.service.impl.iocServiceImpl">
        <property name="mapper" ref="mapper"/>
    </bean>
    <!--这个别名针对ref属性也是可使用的-->
    <bean id="iocMapper" name="mapper" class="IocDemo.dao.impl.iocMapperImpl"/>

2953321-20240625201318336-1034060735.png

5.3 Bean作用范围配置

2953321-20240625201428214-1672645930.png

为什么 Bean 默认是单例的:

  • 资源节约:单例模式确保每个bean在整个应用程序中只有一个实例,这样可以节省内存和CPU资源。对于一些重型对象,频繁创建和销毁会消耗大量资源,使用单例可以显著提高性能。
  • 管理方便:单例bean由Spring容器管理,整个应用程序在启动时创建并初始化它们,然后在整个应用程序生命周期内重用这些实例。这样可以减少复杂性,简化bean的管理和使用。
  • **线程安全:**单例bean通常在初始化时就已经准备好可以使用,而不是在每次请求时创建新实例。因此,如果单例bean是线程安全的,它们可以安全地被多个线程共享,而不需要额外的同步开销。
  • 一致性:用单例bean可以确保同一类型的bean在整个应用程序中具有一致的状态。这对于某些全局配置或共享资源来说特别重要,例如数据库连接池、缓存管理器等。

适合交给容器进行管理的 bean

  • 表现层对象 controller

  • 业务层对象 service

  • 数据层对象 dao

  • 工具对象 utils

不适合交给容器进行管理的 bean

  • 封装实体的域对象

六,Bean的初始化

6.1 构造方法初始化Bean

bean本质上就是对象,创建 bean 使用构造方法完成。

  • Spring底层是通过反射,调用无参构造来实现实例化bean的

2953321-20240625202546397-2145458323.png

6.2 静态工厂初始化Bean

2953321-20240625203643838-1289471420.png

这种方式一般是为了兼容早期的遗留系统来使用的,了解即可。之所以必须用静态工厂是因为静态工厂里面包含了一些实例化类必须的操作。

6.3 实例工厂初始化Bean

2953321-20240627094600675-649963155.png

6.4 实现FactoryBean初始化Bean

在很多的 Spring 集成框架里面都是使用这种方式的。

  1. 工厂类:

    public class UserDaoFactory implements FactoryBean<IUseDao> {
        @Override
        public IUseDao getObject() throws Exception {
            //这个方法用来创建bena对象
            return new UserDaoImpl();
        }
    
        @Override
        public Class<?> getObjectType() {
            //这个方法用来返回bean对象的字节码对象
            return IUseDao.class;
        }
    
        @Override
        public boolean isSingleton() {
            //这个用来决定创建的bean对象是单例的还是非单例的
            //true是单例
            //false是非单例
            return false;
        }
    }
    
  2. xml 配置

    <bean id="UserDaoFactory" class="IocDemo.factory.UserDaoFactory" />
    <!--直接将工厂给配置成bean即可-->
    

七,Bean的生命周期

生命周期:从创建到消亡的完整过程

  • bean生命周期:bean从创建到销毁的整体过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

Bean 的生命周期:

  • 初始化容器:
    1. 创建对象 (内存分配)

    2. 执行构造方法

    3. 执行属性注入 (set 操作)

    4. 执行 bean 初始化方法

    5. 使用 bean

  • 执行业务操作
    1. 关闭/销毁容器
    2. 执行bean销毁方法

7.1 生命周期控制

使用 xml 方式配置生命周期控制

2953321-20240627153708658-1107467728.png

使用接口实现生命周期的控制:

2953321-20240627153750616-571133853.png

7.2 Bean的销毁

2953321-20240627153853330-469107752.png

八,依赖注入

8.1 Setter注入

8.1.1 注入简单类型

2953321-20240627161612165-1538709048.png

8.1.2 注入引用类型

2953321-20240627160900004-962998047.png

8.2 构造器注入

8.2.1 注入简单类型

2953321-20240627162037473-773641321.png

使用构造器注入中的 name 指的是形参名

8.2.2 注入引用类型

2953321-20240627162031128-586652550.png

8.2.3 参数适配

由于使用构造器注入使用的是形参名匹配,导致耦合度过高,故有如下方式进行解耦合

2953321-20240627162103664-1138592171.png

8.3 依赖注入选择

  • 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
  • 可选依赖使用setter注入进行,灵活性强
  • Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
  • 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
  • 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
  • 自己开发的模块推荐使用setter注入

8.4 自动装配

IoC 容器根据bean 所依赖的资源在容器中自动査找并注入到 bean 中的过程称为自动装配

自动装配方式:

  • 按类型(常用)
  • 按名称
  • 按构造方法
  • 不启用自动装配

2953321-20240627163611099-2066615792.png

byType

  • 那么在 bean 容器中这个类型的 bean 只能有一个要不然会报错,因为 Spring 不知道选择哪一个 bean 注入

  • 按类型,那个注入的 bean 不需要写 id

byName:

  • 他是通过setXXX来识别的,加上我选择是setA,并且存在A这个Bean就会注入A,如果Bean的id叫A但set方法是setB会出现识别失败的情况

构造方法自动注入是不推荐使用的,因为是强依赖注入,故不采用

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
  • 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

8.5 集合注入

2953321-20240627165222563-327782469.png

2953321-20240627165238262-2003825831.png

2953321-20240627165253166-525554654.png

2953321-20240627165302572-2002493071.png

2953321-20240627165312145-589006368.png

如果集合的泛型是引用数据类型的, 那么用 ref 来代替 value 即可

  • <ref bean="beanId"/>
    

九,加载properties文件

2953321-20240627200949370-1489979996.png

2953321-20240627201234105-137741855.png

十,容器

10.1 容器初始化

2953321-20240627204915744-1779031969.png

10.2 获取bean

2953321-20240627204946637-837278743.png

10.3 容器层次结构图

2953321-20240627205348213-814585159.png

10.4 BeanFactory初始化

2953321-20240627205410766-76030686.png

ApplicationContext 也可以延迟加载

  • <bean id="userDao" class="IocDemo.dao.impl.UserDaoImpl" lazy-init="true"/>
    
动物装饰