【Spring5】IOC容器与解耦合(上)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 文章目录1 IOC的概念与刨析1.1 IOC简介1.2 IOC底层原理1.3 IOC容器1.3.1 何为容器?1.3.2 IOC容器的理解2 IOC操作Bean管理2.1 Bean管理2.2 Bean管理xml形式2.2.1 创建对象与注入过程2.2.2 注入空值和特殊符号2.2.3 注入属性2.2.3.1 外部bean与内部bean2.2.3.2 注入集合2.3 工厂Bean2.4 Bean的作用域2.5 Bean的生命周期2.6 xml自动装配(偷懒的技巧)

1 IOC的概念与刨析

1.1 IOC简介

 控制反转(Inversion of Control),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。

 其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫依赖查找(Dependency Lookup)。

 通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。


通俗一点,解释如下:


控制反转,把对象的创建和对象之间调用的过程交给Spring进行管理;

使用IOC目的:为了降低耦合度。

1.2 IOC底层原理

所谓使用IOC的目的就是为了降低耦合度,在软件工程概论中我们知道,衡量一个软件设计好坏的标准,是 高耦合、低内聚。


因此,在刨析IOC底层原理的时候,我们不妨一步步来观察如何将代码之间耦合度慢慢降低


传统方式:


对象UserService依赖于对象User,即对象UserService在初始化或者运行到某一点的时候, 自己必须主动去创建对象User或者使用已经创建的对象User,控制权始终在自己手上。耦合度高! 两个对象关系过于紧密,当User的路径或者User中方法变了,UserService也会跟着变,所谓 牵一发而动全身 就是这个道理。


工厂模式:


通过一个UserFactory工厂,完成了对象的创建操作,降低了UserService和User之间的耦合度, 可是工厂和对象之间还是存在耦合度。 其实,完全消除耦合度是不可能的,只能降低耦合度。显然,工厂模式不是最优解。



引入IOC:


IOC底层原理涉及到xml解析、工厂模式与反射机制。IOC过程如下:


在xml配置文件中配置创建的对象;

<bean id="user" class="com.hxh.User"></bean>
1

假设还是有UserService与User类,想要在UserService类中调用User的方法,因此创建一个UserFactory工厂类,进行具体的操作,与上面讲解不同的是,这里不再直接返回一个对象,而是通过xml解析和反射的方式 做到进一步降低耦合度:

public class UserFactory {
    public static User getUser() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //1.xml解析
        //String classValue = class属性值;
        //2.通过反射创建对象
        Class<?> clazz= Class.forName("com.hxh.User");
        return (User) clazz.newInstance();
    }
}

此时,如果User的路径发生了更改,只需要更改xml文件中的配置,实现了耦合度进一步降低。


1.3 IOC容器

1.3.1 何为容器?

容器的核心是Bean,是豆荚的意思,我们的对象都被装在这个豆荚里统一管理。 可以理解成钞票是你的对象,而你需要把它存储在银行,让银行帮你打理,等你需要钱的时候,银行根据你的需要再把钱打给你… …(我可真是小财迷!)


而在xml里配置的


bean、@repository、 @service、@controller、@component


可以理解成抽象的 map (id-class),在项目启动的时候会读取配置文件里面的bean节点,根据全类名使用反射创建对象放到map里、扫描到打上上述注解的类也是通过反射创建对象放到map里。

此时,map中就放入了我们的对象,接下来我们在代码里需要用到里面的对象时,会通过依赖注入(DI)注入(autowired.resource等注解, xml里bean节点内的ref属性,项目启动的时候会读取xm|节点ref属性根据id注入,也会扫描这些注解,根据类型或id注入)。


1.3.2 IOC容器的理解

IOC思想基于IOC容器完成的,IOC容器的底层是对象工厂


还是再IOC底层原理举的例子,IOC容器会主动创建一个对象User注入到对象UserService需要的地方,从而让User和UserService失去了直接联系。 图示如下:



通过图可以看出来,全部对象的控制权全部上缴给"第三方"IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用, 如果没有这个"粘合剂",对象与对象之间会彼此失去联系。


Spring提供了IOC容器实现的两种方式(接口):


  1. BeanFactory: IOC基本容器的实现,是Spring内部的接口,不提供开发人员进行使用。加载配置文件的时候,不会创建对象,只有在使用的时候才去创建。
  2. ApplicationContext: BeanFactory接口的子接口,提供了更多更强的功能,一般由开发人员使用。加载配置文件的时候就会把配置文件对象进行创建。

2 IOC操作Bean管理

2.1 Bean管理

Bean管理指的是两个操作:

(1)Spring 创建对象;

(2)Spring 注入属性


Bean管理操作有两种方式

方式一:基于xml配置文件实现

方式二:基于注解的方式实现


2.2 Bean管理xml形式

2.2.1 创建对象与注入过程

一.创建对象

在spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象的创建。


<bean id="user" class="com.hxh.User"></bean>
1

在bean标签中,有许多常用的属性:

属性 含义
id 获取对象的唯一标识
class 类全路径
name 与id基本相同,区别是name可以有特殊字符


创建对象,默认执行无参构造方法。

二.注入属性

与JavaSE一样,支持set注入和有参构造注入两种方式。

演示使用set方法进行属性的注入

1.首先创建一个类,类中含有对应的属性和set方法,以Book类为例!

public class Book {
    //创建属性
    private String bname; //书名
    private String bauthor; //作者
    //对应的set
    public void setBname(String bname) {
        this.bname = bname;
    }
    public void setBauthor(String bauthor) {
        this.bauthor = bauthor;
    }
    //为了测试方便
    public void testDemo(){
        System.out.println(bauthor + "--" + bname);
    }
}


相关文章
|
8天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
23 2
|
8天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
16 1
|
1月前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
20天前
|
前端开发 Java Docker
使用Docker容器化部署Spring Boot应用程序
使用Docker容器化部署Spring Boot应用程序
|
22天前
|
Java Docker 微服务
利用Docker容器化部署Spring Boot应用
利用Docker容器化部署Spring Boot应用
44 0
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
35 0
|
2月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
36 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
2月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
76 0
|
2月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
51 0