热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Spring依赖注入(DI)详解[Spring][依赖注入的6种实现方式][setter注入][构造器注入][注解注入][自动装配注入][静态工厂注入][实例工厂注入]

您的“关注”和“点赞”,是信任,是认可,是支持,是动力......如意见相佐,可留言。本人必将竭尽全力试图做到准确和全面,终其一生进行修改补充更新。目录1 依赖注入概述2 依赖注入的多种方式(Bean

您的“关注”和“点赞”,是信任,是认可,是支持,是动力......


如意见相佐,可留言。
本人必将竭尽全力试图做到准确和全面,终其一生进行修改补充更新。

目录
  • 1 依赖注入概述
  • 2 依赖注入的多种方式(Bean 的装配方式)
    • 2.1 基于 XML 的依赖注入
      • 2.1.1 Setter Injection(设置方法注入)
      • 2.1.2 Constructor Injection(构造器注入)
    • 2.2 基于 Annotation(注解)的依赖注入
      • 2.2.1 基于 Annotation(注解)的依赖注入概述
      • 2.2.2 常用注解概述
      • 2.3.3 案例实操,走起
    • 2.3 基于自动装配的依赖注入
    • 2.4 静态工厂注入
    • 2.5 实例工厂注入
  • 【文章其他地址】
    • 微信公众号:码农阿杰
    • CSDN 博客
  • 【参考资料】
    • spring
    • Artifact Repository Browser
    • Apache Commons

1 依赖注入概述

依赖注入,英文叫做 Dependency Injection,简称 DI

DI 和 IoC (《Spring IoC 容器详解》)含义相同,它们是从两个角度描述的同一个概念、做同一件事情。

当某个 Java 实例需要另一个 Java 实例时,使用 Spring 之前都是由调用者创建(使用 new 关键字获得被调用者实例)被调用者的实例,而使用 Spring 框架后,被调用者的实例不再由调用者创建,而是由 Spring IoC 容器创建,这称为控制反转,也即 IoC。

Spring IoC 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,这样,调用者通过 Spring IoC 容器获得被调用者实例,这称为依赖注入,也即 DI。

Bean 的依赖注入方式,或叫 Bean 的装配方式,有多种形式,比如接下来要介绍的基于 XML 的依赖注入(有两种实现方式:Setter Injection 设置注入和 Constructor Injection 构造器注入)、基于 Annotation 的依赖注入、基于自动装配、基于静态工厂的方式的依赖注入和基于实例工厂的方式的依赖注入等。

2 依赖注入的多种方式(Bean 的装配方式)

2.1 基于 XML 的依赖注入


2.1.1 Setter Injection(设置方法注入)

基于设置方法注入,也可以叫做setter方法注入,这是最简单的注入方式。

指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。

案例实操,走你!

目的:在UserService接口的实现类UserServiceImpl中用setter方法初始化UserDao的对象。

具体步骤如下所示,

第一步:在com.manongajie.service包下创建UserService接口。如下图所示:

技术图片

第二步:在com.manongajie.serviceimpl包下创建接口UserService的实现类UserServiceImpl。在类中声明userDao变量,但是没有初始化它,这里就必须要 setter 方法(是 IoC 容器的注入入口。相当于 IoC 容器调用 setter 方法初始化 userDao 变量)了,如下图所示:

技术图片

第三步:在 applicationContext.xml配置文件中添加配置信息。标签中的 name属性值为setXxx()方法的参数(也叫依赖项);ref属性值为 Bean 的nameid值。添加内容,如下图所示:

技术图片

第四步:编写测试类并使用JUnit 测试运行。在com.manongajie.test包下的SpringTest类中创建test2()方法。如下图所示:

技术图片

从上图中可以看出,使用 Spring IoC 容器获取 userService的实例后,调用了该实例的 addUser()方法,在该方法中又调用了 UserDao 接口的实现类 UserDaoImpl 中的 save()方法(userDao 对象就是 IoC 容器自动调用 setter 方法注入的。本例中 setter 方法为 setUserDao() 方法)。

2.1.2 Constructor Injection(构造器注入)

指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法(本文本小节以带参数的构造器进行介绍)实现,每个参数代表一个依赖,Spring 容器会根据 bean 中指定的构造方法参数来决定调用哪个构造函数。

案例实操,走你!

目的:在UserDaoImpl类中创建成员变量userService,使用UserDaoImpl类的构造器注入userService 实例,也就是说 spring 容器在创建 UserDaoImpl类的实例时,也要将 userService实例作为构造器的参数值传到UserDaoImpl类中(配置文件中操作,使用标签,ref属性表示 Bean 的 id)。

具体步骤如下所示,

第一步:直接在之前的项目中操作,在UserDaoImpl类中创建一个成员变量userService,构造器UserService(UserService userService),如下图所示:

技术图片

第二步:配置配置文件,如下图所示:

技术图片

第三步:编写测试类和JUnit 测试运行。如下图所示:

技术图片

从上图中可以看出,通过 Spring 容器获取UserDao的实例后,调用了该实例的save()方法,在该方法中又调用了UserService接口的实现类UserServiceImpl中的addUser()方法(userService 对象就是 spring 容器通过构造器注入的。)

2.2 基于 Annotation(注解)的依赖注入


2.2.1 基于 Annotation(注解)的依赖注入概述

如果应用中 Bean 的数量较多,基于 XML 配置文件实现 Bean 的装配会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。

基于 Annotation(注解)的依赖注入就可以解决这个问题。

2.2.2 常用注解概述



  • @Component
    可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。


  • @Repository
    用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。


  • @Service
    通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。


  • @Controller
    通常作用在控制层(如 Struts2 的 Action),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。


  • @Autowired(在本文 《2.3 基于自动装配的依赖注入》 小节详细介绍)
    用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。


  • @Resource
    其作用与 Autowired 一样。其区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配。

    @Resource 中有两个重要属性:name 和 type。

    Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。
    如果指定 name 属性,则按实例名称进行装配;
    如果指定 type 属性,则按 Bean 类型进行装配。
    如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。


  • @Qualifier
    与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。



2.3.3 案例实操,走起

第一步:导入关键 JAR 包。然后创建 DAO 层接口,在com.manongajie.dao包下创建PersonDao接口,并添加add()方法。如下图所示:

技术图片
第二步:创建 DAO 层接口的实现类。在com.manongajie.daoimpl包下创建PersonDao接口的实现类PersonDaoImpl,并添加 DAO 层 add()方法。对类使用@Repository 注解将 PersonDaoImpl 类标识为 Spring 中的 Bean,其写法相当于配置文件中 的书写。如下图所示:

技术图片
第三步:创建 Service 层接口。图下图所示:

技术图片
第四步:创建 Service 层接口的实现类。如下图所示:

技术图片

第五步:创建 Action 控制层。如下图所示:

技术图片
第六步:创建 Spring 配置文件。需要添加更多的约束文件,如何把约束文件交给 Eclipse 管理,请参见博文《开启 Spring 之旅:第一个 Spring 程序 !》。

技术图片

第七步:创建测试类和 JUnit 运行测试。如下图所示:

技术图片

从上图中可以看出,DAO 层、Service 层和 Action 层的 add()方法都成功输出了结果。
So,使用 Annotation 装配 Bean 的方式已经成功实现了。

2.3 基于自动装配的依赖注入

本文篇幅太长了,另写一文。

请参见博文《Spring 基于自动装配的依赖注入详解》。

2.4 静态工厂注入

需要提供一个静态工厂方法 createBean(),创建 Bean 的实例(是指createBean()方法返回哪个类的实例,就创建哪个类的实例)。
需要在配置文件中,使用 标签的 factory-method 属性,用于告诉 Spring 容器调用工厂类中的 createBean() 方法获取 Bean 的实例。

案例演示,如下所示:

第一步:创建实体类 Person。在com.manongajie.static_factory包下创建。

技术图片
第二步:创建静态工厂类MyBeanFactory,并在类中创建createBean()静态方法,用于创建 Bean 的实例。

技术图片
第三步:创建配置文件。

技术图片
第四步:创建测试类和JUnit 测试运行。

技术图片
从以上运行结果可以看出,使用静态工厂的方式也成功对 Bean 进行了实例化。

2.5 实例工厂注入

使用这种方式,工厂类不再使用静态方法创建 Bean 的实例,而是直接在成员方法中创建 Bean 的实例。

也就是说需要一个成员方法createBean()来创建 Bean 的实例。

在配置文件中,需要实例化的 Bean 也不是通过 class 属性直接指向其实例化的类,而是通过 factory-bean 属性配置一个实例工厂,然后使用 factory-method 属性确定使用工厂中的哪个方法。

案例演示,如下所示:

第一步:创建实体类 Person,并在类中添加say()方法。

技术图片
第二步:创建实例工厂类,并添加成员方法createBean()

技术图片
第三步:创建配置文件。

技术图片
第四步:创建测试类和JUnit 测试运行。

技术图片
从以上运行结果可以看出,使用实例工厂的方式也是可以对 Bean 进行实例化的哦。。

【文章其他地址】

微信公众号:码农阿杰


CSDN 博客


【参考资料】

spring


Artifact Repository Browser


Apache Commons



























推荐阅读
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • Struts2+Sring+Hibernate简单配置
    2019独角兽企业重金招聘Python工程师标准Struts2SpringHibernate搭建全解!Struts2SpringHibernate是J2EE的最 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 标题: ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • Jboss的EJB部署描述符standardjaws.xml配置步骤详解
    本文详细介绍了Jboss的EJB部署描述符standardjaws.xml的配置步骤,包括映射CMP实体EJB、数据源连接池的获取以及数据库配置等内容。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
author-avatar
yoyo_jiawen43
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有