Spring的艺术(二):控制反转(IOC)和依赖注入(DI)的完美实现

简介: IOC叫做控制反转,从本质上讲,IOC就是把原本由程序员创建的对象的这个动作交给Spring去实现,程序员无需再去管理对象的创建,这种方式可以大大减少系统的偶尔性。没有IOC之前,对象的创建和对象间的依赖关系都完全编码在程序中,使用IOC之后,对象的创建由程序自己控制,使得程序解耦合。IOC并不是一种技术,他是一种思想,即控制权反转的思想,DI(依赖注入)则是Spring实现IOC的方法。Spring容器在初始化时根据配置文件或元数据创建和组织对象存入容器中,需要使用时再从IOC容器中获取。

听说微信搜索《Java鱼仔》会变更强哦!


本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看哦

本章的内容基于官方文档编写:docs.spring.io/spring-fram…


Spring版本为5.2.9


(一)概述


IOC叫做控制反转,从本质上讲,IOC就是把原本由程序员创建的对象的这个动作交给Spring去实现,程序员无需再去管理对象的创建,这种方式可以大大减少系统的偶尔性。


没有IOC之前,对象的创建和对象间的依赖关系都完全编码在程序中,使用IOC之后,对象的创建由程序自己控制,使得程序解耦合。


IOC并不是一种技术,他是一种思想,即控制权反转的思想,DI(依赖注入)则是Spring实现IOC的方法。


Spring容器在初始化时根据配置文件或元数据创建和组织对象存入容器中,需要使用时再从IOC容器中获取。


网络异常,图片无法展示
|


(二)创建第一个Spring程序


1、首先确保你已经创建完成Maven项目并引入了Spring依赖,这里只需要引入spring-webmvc即可


<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.9.RELEASE</version></dependency>

2、创建实体类


publicclassUser {
privateintid;
privateStringname;
//省略构造方法、get、set、toString方法}

3、基于 XML 配置容器


<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--使用spring创建对象--><beanid="user"class="com.javayz.pojo.User"><propertyname="id"value="1"/><propertyname="name"value="javayz"/></bean></beans>

其中id用来标识这个bean,class指向该类的全限定名


4、实例化容器


@Testpublicvoidtest(){
//获取Spring的上下文对象ApplicationContextcontext=newClassPathXmlApplicationContext("bean.xml");
//获取beanUseruser= (User) context.getBean("user");
System.out.println(user.toString());
}


只需要上面的四步,我们就实现了通过Spring创建对象。这个过程就是控制反转,由Spring的IOC容器来控制对象的创建权。


(三)IOC创建对象的方式


3.1、默认使用无参构造方法创建对象


这一点很好验证,如果我们把User对象的无参构造方法给去掉,你可以看到这样的报错信息:


网络异常,图片无法展示
|

当然也可以使用有参构造方法,我们需要用到另外一个参数constructor-arg


<!--使用spring创建对象--><beanid="user"class="com.javayz.pojo.User"><constructor-argindex="0"value="1"/><constructor-argindex="1"value="javayz"/></bean>

上面是通过下标的实现方式,再来看一下通过变量名的方式


<beanid="user"class="com.javayz.pojo.User"><constructor-argname="id"value="1"/><constructor-argname="name"value="javayz"/></bean>


构造器注入是Spring依赖注入的一种方式,接下来我会把其他的几种注入方式都介绍一遍。


(四) Spring的配置


Spring的配置文件没有太多参数,这里就来总结一下


4.1 alias标签


别名就是你可以给bean的id换一个其他的名字


<beanid="user"class="com.javayz.pojo.User"><constructor-argname="id"value="1"/><constructor-argname="name"value="javayz"/></bean><aliasname="user"alias="user2"/>

现在使用user和user2都可以访问到这个bean


4.2 bean标签


bean标签是通过xml配置中最常用的,主要会用的几个参数


id :bean的唯一标识


class :bean对象所对应的全限定名


name : 别名,可以取多个名字


scope : 作用域,Spring默认作用域是singleton


<beanid="user"class="com.javayz.pojo.User"name="user3"scope="singleton"><constructor-argname="id"value="1"/><constructor-argname="name"value="javayz"/></bean>

4.3 import


import标签可以把多个xml配置文件导入到一个总的配置文件中供程序员调用。


<importresource="bean.xml"/>

4.4 cp命名空间


c命名空间和p命名空间可以简化xml文件


使用时首先需要引入xmlns


xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

c命名空间可以直接在bean标签下注入构造器


网络异常,图片无法展示
|


p命名空间可以直接注入属性的值


网络异常,图片无法展示
|


(五)依赖注入的两种方式


5.1 构造器注入


构造器注入就是前面所讲的方式,通过无参或者有参的构造方法注入对象。


5.2 Set方法注入


Set方法可以注入更加复杂的对象


网络异常,图片无法展示
|


官网说Set方法支持上面这九种方式的注入,我们来模拟一下 我们新建一个User类包含上面的所有复杂类型:


publicclassUser {
privateStringname;
privateFatherfather;
privateString[] arrays;
privateList<String>list;
privateMap<String,String>map;
privateSet<String>set;
privatePropertiesprop;
privateStringisNUll;
//不需要构造方法 , 省略get、set、toString }

然后在bean的xml中来注入所有值

<?xmlversion="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="father"class="com.javayz.pojo.Father"/><beanid="user"class="com.javayz.pojo.User"><!--基础类型用value注入--><propertyname="name"value="javayz"/><!--bean注入,使用ref --><propertyname="father"ref="father"/><!--数组注入,使用array --><propertyname="arrays"><array><value>array1</value><value>array2</value></array></property><!--list注入,使用list --><propertyname="list"><list><value>list1</value><value>list2</value></list></property><!--map注入,使用map --><propertyname="map"><map><entrykey="1"value="a"/><entrykey="2"value="b"/></map></property><!--set注入,使用set --><propertyname="set"><set><value>set1</value><value>set2</value></set></property><!--Prop注入,使用prop --><propertyname="prop"><props><propkey="key1">value1</prop><propkey="key2">value2</prop></props></property><!--NUll注入,使用null --><propertyname="isNUll"><null/></property></bean></beans>

(六)总结


上面展示的所有内容其实都可以在官方文档中找到,只不过官方文档内容会更加繁琐,并且没有官方的中文版本,所以我的建议是官方文档是第一手资料,但是你也可以看我的系列博客,我会尽可能的将官方文档的内容变得通俗易懂。

相关文章
|
20天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
12天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
25 0
|
1月前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
28 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
1月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
30 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
1月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
65 0
|
1月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
45 0
|
6月前
|
XML Java 数据格式
深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓
在本文中,我们将介绍 IoC(控制反转)和 DI(依赖注入)的概念,以及如何在 Spring 框架中实现它们。
390 0
|
6月前
|
Java Spring
Spring5深入浅出篇:Spring中ioc(控制反转)与DI(依赖注入)
Spring5深入浅出篇:Spring中ioc(控制反转)与DI(依赖注入)
|
6月前
|
Java API Spring
Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC
Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC
|
Java 测试技术 Spring
Spring入门&控制反转(或依赖注入)&AOP的关键概念& 多配置文件&与web集成(二)
Spring入门&控制反转(或依赖注入)&AOP的关键概念& 多配置文件&与web集成