Spring常见的DI方式

字段注入(Field Injection)

  • 在字段上使用@Autowired/Resource注解

  • 字段注入是日常开发中使用最多的一种注入方式,它的实现代码如下:

    @Autowired
    private UserService userService;
    优点

    属性注入最大的优点就是实现简单、使用简单,只需要给变量上添加一个注解 @Autowired,就可以在不 new 对象的情况下,直接获得注入的对象了(这就是 DI 的功能和魅力所在),所以它的优点就是使用简单。

    缺点

    属性注入虽然使用简单,但也存在着很多问题,甚至编译器 Idea 都会提醒 “不建议使用此注入方式”

    1、功能性问题:无法注入一个不可变的对象(final 修饰的对象)

    2、通用性问题:只能适应于 IoC 容器

    3、设计原则问题:更容易违背单一设计原则

Setter注入(Setter Injection)

  • 调用Setter的方法注入依赖

  • 实现代码如下:

    // Setter 注入
    private UserService userService; @Autowired
    public void setUserService(UserService userService) {
    this.userService = userService;
    }

    从上面代码可以看出,Setter 注入比属性注入要麻烦很多。

    要说 Setter 注入有什么优点的话,那么首当其冲的就是它完全符合单一职责的设计原则,因为每一个 Setter 只针对一个对象。

    但它的缺点也很明显,它的缺点主要体现在以下 2 点:

    1、不能注入不可变对象(final 修饰的对象);

    2、注入的对象可被修改。

    • Setter 注入提供了 setXXX 的方法,意味着你可以在任何时候、在任何地方,通过调用 setXXX 的方法来改变注入对象,所以 Setter 注入的问题是,被注入的对象可能随时被修改。

构造器注入(Constructor Injection)

  • 利用构造方法的参数注入依赖

  • 构造方法注入是 Spring 官方从 4.x 之后推荐的注入方式,它的实现代码如下:

    // 构造方法注入
    private UserService userService;
    @Autowired
    public UserController(UserService userService) {
    this.userService = userService;
    }

    如果当前的类中只有一个构造方法,那么 @Autowired 也可以省略

    优点

    构造方法注入相比于前两种注入方法,它可以注入不可变对象,并且它只会执行一次,也不存在像 Setter 注入那样,被注入的对象随时被修改的情况,它的优点有以下 4 个:

    1、可注入不可变对象(final 修饰的对象)

    2、注入对象不会被修改

    • 构造方法注入不会像 Setter 注入那样,构造方法在对象创建时只会执行一次,因此它不存在注入对象被随时(调用)修改的情况。

    3、注入对象会被完全初始化

    • 因为依赖对象是在构造方法中执行的,而构造方法是在对象创建之初执行的,因此被注入的对象在使用之前,会被完全初始化,这也是构造方法注入的优点之一。

    4、通用性更好

    • 构造方法和属性注入不同,构造方法注入可适用于任何环境,无论是 IoC 框架还是非 IoC 框架,构造方法注入的代码都是通用的,所以它的通用性更好。

常用注入方式总结

依赖注入的常见实现方式有 3 种:属性注入、Setter 注入和构造方法注入。

  • 其中属性注入的写法最简单,所以日常项目中使用的频率最高,但它的通用性不好;
  • 而 Spring 官方推荐的是构造方法注入,它可以注入不可变对象,其通用性也更好;
  • 如果是注入可变对象,那么可以考虑使用 Setter 注入。

三种注入方式的优缺点

  • 构造器注入:强依赖性(即必须使用此依赖),不变性(各依赖不会经常变动)
  • Setter注入:可选(没有此依赖也可以工作),可变(依赖会经常变动)
  • Field注入:大多数情况下尽量少使用字段注入,一定要使用的话, @Resource相对@Autowired对IoC容器的耦合更低

@Autowired 和 @Resource 有什么区别

@Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同。

  • 来源不同:来自不同的“父类”,@Autowired是Spring提供的,@Resource是JSR-250提供的

  • 依赖查找顺序不同

    依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当前类中。

    @Autowired 查找顺序: 是先根据类型(byType)查找,如果存在多个(Bean)再根据名称(byName)进行查找

    @Resource 查找顺序: 是先根据名称(byName)查找,如果(根据名称)查找不到,再根据类型(byType)进行查找

  • 支持的参数不同:@Autowired 只支持设置一个 required 的参数,而 @Resource 支持 7 个参数

  • 适用对象不同:@Autowired可以对构造器、方法、参数、字段使用,@Resource只能对方法、字段使用

  • 依赖注入的支持不同:@Autowired 支持属性注入、构造方法注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入

为什么IDEA只对@Autowired警告

在使用IDEA开发的时候有没有注意到过一个提示,在字段上使用Spring的依赖注入注解@Autowired后会出现如下警告:

Field injection is not recommended (字段注入是不被推荐的)

但是使用@Resource却不会出现此提示

  • @Autowired是Spring提供的,它是特定IoC提供的特定注解,这就导致了应用与框架的强绑定,一旦换用了其他的IoC框架,是不能够支持注入的。

  • 而 @Resource是JSR-250提供的,它是Java标准,我们使用的IoC容器应当去兼容它,这样即使更换容器,也可以正常工作。

用@RequiredArgsConstructor代替@Autowired

我们都知道注入一个bean有三种方式(set注入, 构造器注入, 注解注入),spring推荐我们使用构造器的方式注入Bean。

@RequiredArgsConstructor注解,生成带有必需参数的构造函数。必需的参数是最终字段和具有约束的字段,例如@NonNull。

这个注解是基于lombok的使用时必须导入lombok包。

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>

同时注意几点:

  1. 声明的变量必须为final

  2. 根据构造器注入的,相当于当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。基于构造方法为属性赋值,容器通过调用类的构造方法将其进行依赖注入。

当我们需要注入Bean的时候可以直接在类上添加@RequiredArgsConstructor注解使用,代替了Autowrited注解。

@RequiredArgsConstructor
@RestController
@RequestMapping("/test")
public class TestController {
private final TestService testService;
private final UserService userService;
}

Spring注解之依赖注入@Autowired和@Resource的更多相关文章

  1. 07 Spring框架 依赖注入(四)基于注解的依赖注入

    前面几节我们都在使用xml进行依赖的注入,但是在实际的开发中我们往往偏爱于使用注解进行依赖注入,因为这样更符合我们人的思维,并且更加快捷,本节就来讲述Spring基于注解的依赖注入: 信息注入注解 @ ...

  2. Spring下的@Inject、@Autowired、@Resource注解区别(转)

    1.@Inject javax.inject JSR330 (Dependency Injection for Java) 这是JSR330中的规范,通过AutowiredAnnotationBean ...

  3. Spring:基于注解的依赖注入的使用

    1.什么是pojo?什么是bean? 首先,在之前几篇Spring的介绍文章当中,自己都提到了一个名词叫做POJO类,但是在回顾Spring的注解的使用的时候,去形容java当中的对象还有一个名词是叫 ...

  4. Spring Boot2(007):关于Spring beans、依赖注入 和 @SpringBootApplication 注解

    一.关于Spring beans 和 依赖注入(Dependency Injection) spring boot 和 Spring 全家桶无缝衔接,开发过程中可以很轻松地使用 Spring 全家桶的 ...

  5. spring 四种依赖注入方式以及注解注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...

  6. Spring-Context的注解实现依赖注入功能

    使用Spring-Context的注解实现依赖注入功能. Demo要点: 本例子中主要使用Annotation功能来实现对MoviceService的注入.我们将Cinema.java的头部标注为@C ...

  7. spring六种种依赖注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...

  8. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  9. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  10. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->Spring Framework的依赖注入和控制反转

    Dependency Injection and Inversion of Control 1.概述: 1.1相关概念 bean:由IoC容器所管理的对象,也即各个类实例化所得对象都叫做bean 控制 ...

随机推荐

  1. 使用SQL Server语句统计某年龄段人数占总人数的比例(多层查询语句嵌套-比例分析)

    需求:需统计出某个集合内,某个段所占的比例,涉及SELECT查询语句的嵌套,如有疑问可留言. 如下: --按性别进行年度挂号年龄段分析--男SELECT 年龄段,SUM(人数) 数量,cast(cas ...

  2. 简述 js 的代码整洁之道

    文章参考出自:https://juejin.cn/post/7224382896626778172 前言 为什么代码要整洁? 代码质量与整洁度成正比.有的团队在赶工期的时候,不注重代码的整洁,代码写的 ...

  3. Cesium教程10-把影像和天空改成背景图片

    在使用Cesium引擎时,我们经常要使用大屏适配导致地球或者模型的黑色天空盒和大屏的样式不匹配造成场景不好看的情况,这样就可以用到我们修改Cesium的天空为纯色背景,与大屏更适配,直接上代码. &l ...

  4. java学习之旅(day.21)

    HTML 初识HTML HTML: Hyper Text Markup Language(超文本标记语言) 超文本包括文字.图片.音频.视频.动画等 W3C标准 W3C :World Wide Web ...

  5. AIRIOT物联网低代码平台如何配置Modbus RTU协议?

    MBRTU即MODBUS RTU的简称,MODBUS是OSI模型第7层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信.平台的MBRTU协议是建立在TCP协议之上的 ...

  6. GROUP BY clause and contains nonaggregated 报错处理

    1055 - Expression #16 of SELECT list is not in GROUP BY clause and contains nonaggregated column 报错处 ...

  7. springcloud整合stream解决项目升级的多个消息中间件的收发问题

    cloud stream (一)简介Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架.它可以基于 Spring Boot 来创建独立的.可用于生产的 Spring ...

  8. Instsrv.exe 与 Srvany.exe 安装Windows服务

    原理:Instsrv.exe可以给系统安装和删除服务 Srvany.exe可以让exe程序以服务的方式运行(Srvany只是exe注册程序的服务外壳,可以通过它让我们的程序以SYSTEM账户活动,随电 ...

  9. Android 13 - Media框架(11)- MediaCodec(一)

    关注公众号免费阅读全文,进入音视频开发技术分享群! MediaCodec 是 Android 平台上音视频编解码的标准接口,无论是使用软解还是硬解都要通过调用 MediaCodec来完成,是学习 An ...

  10. 「C++」论高精度

    大家好,我是Charzie.在编程领域,高精度计算是一个常见的问题.当标准的整型或浮点型无法满足我们的计算需求时,高精度计算就显得尤为重要.在C++中,虽然标准库没有直接提供高精度数据类型,但我们可以 ...