关于后端:Spring-核心概念之一-IoC

30次阅读

共计 6639 个字符,预计需要花费 17 分钟才能阅读完成。

前言

欢送来到本篇文章!通过上一篇什么是 Spring?为什么学它?的学习,咱们晓得了 Spring 的基本概念,晓得什么是 Spring,以及为什么学习 Spring。明天,这篇就来说说 Spring 中的外围概念之一 IoC。

IoC 这个概念对于初学者来说还真不是很好了解,我就是那个了解不了的初学者。那时候,学起来很费解,只是迷迷糊糊晓得了一些概念名词,管制反转,依赖注入。

当初,我从新梳理这些常识,尽量写分明什么是 IoC 以及相干的常识,如有谬误,敬请斧正!好了废话不多说,进入正题!

什么是 IoC?什么是 Spring IoC 容器?

IoC(Inversion of Control),即管制反转,也被称为依赖注入(Dependency Injection,DI)

如果有对「依赖」不太明确的敌人,那么能够去看上一篇,在上一篇中,咱们通过 Employee 和 Department 的例子解释了何为「依赖」

IoC 是一种定义对象之间依赖关系的过程。

在 Spring 没呈现之前,当一个对象须要应用其余对象来实现某些操作,就须要咱们本人去创立或查找这些依赖的对象。

当初,有了 Spring,咱们的对象交给 Spring 治理,这些对象能够了解为寄存在一个容器中的,这个容器就称为 Spring IoC 容器。在 IoC 容器中,对象不再本人治理它们的依赖,而是 通过构造方法参数、工厂办法的参数或者在对象创立后通过属性设置来定义它们的依赖关系

Spring 的 IoC 容器负责在创建对象时注入它们依赖的其余对象,也就是主动地把依赖的对象提供给须要它们的对象。这样一来,对象不再须要被动去查找或创立它们的依赖,而是由容器在创建对象时帮忙它们实现依赖注入的过程。

管制反转的概念次要是与传统的间接结构(即 new 操作)来管制对象依赖的形式相同。传统形式中,一个对象通常会间接创立或查找它所依赖的其余对象,而在 IoC 中,对象将本身的控制权交给了容器,容器负责管理对象的创立和依赖注入,因而被称为「管制反转」。

初次见面 BeanFactory 和 ApplicationContext

在 Spring Framework 中,org.springframework.beansorg.springframework.context 包是 Spring IoC 容器的根底。

上面介绍两个新手村的搭档给大家意识,BeanFactory 接口和它的子接口 ApplicationContext 接口。

BeanFactory 接口提供了一个高级配置机制,可能治理任何类型的对象。

对于它的子接口 ApplicationContext 来说,它的子接口减少了以下性能:

  • 更容易与 Spring AOP 个性集成
  • 音讯资源解决(用于国际化)
  • 事件公布
  • 应用程序层特定上下文,例如 WebApplicationContext,用于 Web 应用程序。

简而言之,BeanFactory 提供配置框架和基本功能,而 ApplicationContext 增加了更多企业特定性能。

什么是 Bean?

在 Spring 中,形成应用程序骨干并由 Spring IoC 容器治理的对象称为 Bean。Bean 是由 Spring IoC 容器实例化、组装和治理的对象。否则,Bean 只是咱们应用程序中泛滥对象中的一个一般的对象而已。

Bean 及其相互依赖关系是反映在容器应用的 配置元数据(Configuration Metadata)中的,这个配置元数据能够用 XML、Java 注解或 Java 代码示意。

提醒:如果你和我一样比拟喜爱深究这些英文单词的中文意思,当初的我给你个倡议:

就是感觉没必要深究

比如说 Bean,中文是什么意思,你去找翻译,发现翻译是「豆」,还有相似 JavaBean,翻译是「Java 豆」,这些都是毫无意义的翻译,所以没必要晓得它的中文意思是什么,Bean 就是 Bean,Bean 就是被 Spring IoC 容器治理的对象,这就是 Bean;JavaBean 则是只提供 setter 和 getter 的纯对象,自身没有任何业务逻辑,这就是 JavaBean。

容器是谁?

咱们始终谈到「容器」,那么容器到底是什么呢?嘿嘿,容器马上就揭晓了!

实际上,Spring 的 IoC 容器就是由 org.springframework.context.ApplicationContext 接口来代表的。这个容器承当着实例化、配置和组装 Bean 的责任。

容器通过读取配置元数据来理解如何创立、配置和组装对象,同时也容许咱们形容应用程序中各个对象之间的简单依赖关系。目前从本系列的角度来看,咱们会应用传统的 XML 形式来定义配置元数据,这是咱们须要学习和理解的,后续能力更好地了解应用 Java 注解或代码作为配置元数据的形式。

Spring 为咱们提供了多个 ApplicationContext 接口的实现。在独立的应用程序中,常见的实例化形式是创立 ClassPathXmlApplicationContextFileSystemXmlApplicationContext 的一个实例。

不过,在咱们日常的开发和工作中,咱们基本上不须要显式地去实例化一个或多个 Spring 容器。特地是在 Web 应用程序的场景下,通常只需在 web.xml 文件中简略地编写约 8 行规范的 XML 配置即可实现(你能够参考一些不便的形式来初始化 Web 应用程序的 ApplicationContext)。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

所以,容器终于来啦!它就是 Spring 的 IoC 容器,负责管理 Bean 的实例化、配置和组装,而咱们能够通过配置元数据来形容应用程序中的对象和它们之间的依赖关系。记住,咱们个别不须要手动实例化 Spring 容器,特地是在 Web 应用程序中。

Spring IoC 容器怎么运行的?

从顶层上来看,Spring IoC 是这样运行的,就是将咱们应用程序中的各种业务对象与配置元数据联合起来,使得咱们在初始化 ApplicationContext 之后,有一个残缺配置的、可用的应用程序。

什么是配置元数据?

先说个论断,目前日常工作中,配置元数据根本都是以 Java 注解或者 Java 代码的形式来提供给 Spring 容器的,不过 XML 的形式咱们也要学习,对于后续学习是有帮忙的。

「配置元数据」是 Configuration Metadata,不是 Configure Metadata,这里的「配置」二字 是名词,不是动词,千万不要了解成去配置元数据。

这个配置元数据,理论就是用来形容配置的数据,下面我也说了,咱们能够用 Java 注解或者 Java 代码的形式来形容配置,也能够用 XML 的形式来形容数据。

所以当初,置信你曾经明确何为配置元数据了,所以学习下以 XML 格局的文件作为配置元数据。

XML 格局的配置元数据

配置元数据以简略直观的 XML 格局提供,这也是本系列前大半局部内容用来传播 Spring IoC 容器要害概念和个性的形式,也正如后面说的,学习 XML 的配置形式,便于咱们后续学习 Java 注解或者 Java 代码的配置形式。

上面的示例展现了基于 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">

    <bean id="..." class="...">  
        <!-- 该 bean 的协作者和配置写在此处 -->
    </bean>

    <bean id="..." class="...">
        <!-- 该 bean 的协作者和配置写在此处 -->
    </bean>

    <!-- 更多的 bean 定义写在此处 -->

</beans>

下面的示例中,次要应用了 <bean> 元素(或者说标签),该元素有两个属性,idclass

  • id 属性:它是一个字符串,用于标识单个 bean 定义。
  • class 属性:它定义了 bean 的类型,并应用齐全限定类名(又称全限定名、全类名。多种叫法,都是同一个货色)。

咱们习惯说把对象交给 Spring IoC 容器治理,那你如何个交法呢

下面的 XML 曾经给出了答案,就是定义 Bean,咱们每定义一个 Bean,就是将对应的类的对象交给了 Spring IoC 容器了

这些 Bean 的定义就是形成咱们应用程序中的各种理论对象。个别咱们在开发的时候,都会分档次的,管制层、业务层、长久层、体现层(视图层)或者其余档次,而后咱们就会定义业务层对象、长久层对象、体现层对象等等。

在上一篇中,我举了个例子,员工和部门的,让这两个货色交给了 Spring IoC 治理了,实际上,在日常开发中,是不会这样做的,不会配置细粒度的畛域对象(Domain Object)。因为个别这些畛域对象都是在业务层和长久层中创立或者加载的。

如何实例化一个 Spring IoC 容器?

下面我也说过,在咱们日常的开发和工作中,咱们基本上不须要显式地去实例化一个或多个 Spring 容器的。

然而咱们当初在学习,就有必要理解如何手动去实例化一个 Spring IoC 容器。

一行代码就可能实例化一个 Spring IoC 容器:

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

在 XML 为配置元数据的状况下,咱们能够创立一个 ClassPathXmlApplicationContext 对象,它是 ApplicationContext 的一个实现类,提供给咱们的构造函数的参数是一条或多条门路是资源字符串,它让容器从各种内部资源(如本地文件系统、Java CLASSPATH 等)加载配置元数据,这样咱们就实例化一个 Spring IoC 容器,context 对象就是这个容器了。

当初咱们将长久层的对象和业务层的对象定义到 XML 中,先创立好须要的类和接口:

接着,在 daos.xml 中定义如下两个 bean,交给 Spring IoC 治理:

<?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
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="roleDao" class="cn.god23bin.demo.dao.impl.RoleDaoImpl">
        <!-- 该 bean 的协作者和其余配置 -->
    </bean>

    <bean id="userDao" class="cn.god23bin.demo.dao.impl.UserDaoImpl">
        <!-- 该 bean 的协作者和其余配置 -->
    </bean>

    <!-- 其余的长久层的 bean 定义在这里 -->

</beans>

services.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
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 引入另一个 XML 定义的 bean -->
    <import resource="daos.xml"/>

    <bean id="userService" class="cn.god23bin.demo.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao" />
        <property name="roleDao" ref="roleDao" />
    </bean>

    <!-- 其余的业务层的 bean 定义在这里 -->

</beans>

services.xml 中,应用 <import /> 能够让 Bean 的定义逾越 XML 文件。个别每个独自的 XML 配置文件代表了咱们利用中的一个逻辑层或者模块,就如同这里的 daos.xmlservices.xml

应用 Spring IoC 容器

咱们把对象交给了 Spring IoC 容器治理,让它帮咱们创建对象以及解决对象之间的依赖关系。

在下面的 XML 中,咱们定义了 UserServcie 对象,即把 UserService 这个对象交给了 Spring IoC,那么如何从容器获取它呢?

ApplicationContext 是一个高级工厂的接口,可能保护不同 Bean 及其依赖关系的注册表。咱们通过应用办法 T getBean(String name, Class requiredType),就能够获取到咱们须要的 Bean 对象。

代码如下:

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
UserService userService = context.getBean("userService", UserService.class);
String roleList = userService.getRoleList();
String username1 = userService.getUsernameById(23L);
String username2 = userService.getUsernameById(24L);
System.out.println("roleList =" + roleList + "| username1 =" + username1 + "| username2 =" + username2);

输入:

总结

以上,就是本文的所有内容,次要讲了什么是 Spring IoC 容器,介绍了 BeanFactoryApplicationContext

实际上这个 ApplicationContext 就代表容器,它会读取咱们的配置元数据,这样它就晓得该去治理哪些对象了。

也介绍了什么是 Bean,实际上就是被容器治理的对象,都是所谓的 Bean,也习惯称为 Bean 对象。

还介绍了 Spring IoC 容器从顶层上来看是怎么运行的,就是将各种业务对象和配置元数据相结合,组成一个残缺配置的、可用的应用程序。

对于配置元数据,这个能够有多种形式,能够是 XML,能够是 Java 注解,能够是 Java 代码。

最初就介绍了如何去实例化并应用 Spring IoC 容器,尽管咱们日常开始是不会这样去做的,不会去创立一个容器,而后通过容器的 getBean 去获取 Bean 进行操作,然而咱们就是须要理解学习,因为这些就是 Spring 的根底。

最初的最初

心愿各位屏幕前的 靓仔靓女们 给个三连!你轻轻地点了个赞,那将在我的心里世界削减一颗亮堂而夺目的星!

咱们下期再见!

正文完
 0