Spring -- DI

文章目录

  • 一、什么是DI
  • 二、注入的三种方式
    • 2.1 属性注入 @Autowired
      • 使用方法
      • @Autowired存在的问题以及解决方法
      • @Autowired问题的解决方法
    • 2.2 构造方法注入
    • 2.3 setter方法注入
    • 2.4 三种注入方式优缺点分析

一、什么是DI

  1. 概念:DI(依赖注入)就是当我们把依赖对象取出来(创建好后),赋值给该对象的属性
  2. DI的其他翻译:属性装配、依赖装配

二、注入的三种方式

注入只是去拿,但是有没有,是要依靠【Spring实现的loC的方式】

2.1 属性注入 @Autowired

使用方法

  1. @Autowired 作用:告诉Spring我们需要这个对象,去loC容器里拿
  2. @Autowired 注入原则
    • 在注入时,是根据类型去注入的
    • 如果一个类型存在多个对象时,优先名称匹配,如果名称都匹配不上,就会报错。
@Controller
public class TestController {@Autowiredprivate UserService userService;public void doController(){userService.doService();System.out.println("这是Controoler注解");}
}@Service
public class UserService {public void doService(){System.out.println("这是Service注解");}
}
  1. 关于报错:因为@Autowired不是官方推荐写法,所以IDEA可能会报错。但即便如此,由于操作简单,使用量依旧很高
  2. 使用Debug查看当前变量的值:Debug状态下,选中某个变量,选择“Evaluate Expression……”可以进行数值模拟

@Autowired存在的问题以及解决方法

因为构造方法注入和Setter注入都是依据@Autowired实现的,所以它们也存在下面的问题

  1. 有多个类型时要根据名称去拿,有报错的风险
  2. 没有办法去注入一个由final修饰的属性:因为final是不可变的,要求是在定义期间或初始化期间给其赋值
  3. 使用量太高了,可能会滥用
  4. 违反了软件设计的单一原则

@Autowired问题的解决方法

【1】方法介绍

  1. 让属性名和你需要的对象名称一致:这样@Autowired就可以根据名称匹配

  2. 如果不想保持一致:使用@Primary、@Qualifier

    • @Primary:标识默认的对象
    • @Qualifier:指定要使用的Bean名称
      • 既然@Autowired没办法加上属性名,我们就用其他的注解来给其加上属性名
    • @Resource:通过描述bean的信息,去指定要用哪个
  3. 重命名Bean

  4. @Autowird VS @Resource

    • 提供者不同:ctrl或选中注解就可以出现该注解的相关信息,点击小圆球可以定位包。rt是jdk的包。
      • @Autowired 是Spring框架提供的注解,而@Resource是JDK提供的注解
    • 注入方式
      • @Autowired 默认是按照类型注入,如果同一个类型存在多个,再按照名称匹配,如果名称匹配不上,就会报错
      • @Resource 支持更多的参数设置,例如 name 设置,可以根据名称获取 Bean

【2】方法的具体使用

  1. 使用@Primary
@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Primary@Beanpublic UserInfo userInfoL(){UserInfo userInfo = new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("123456");return userInfo;}}@Controller
public class TestController {@Autowiredprivate UserInfo userInfo;public void doController(){System.out.println(userInfo); //lisi}
}
  1. 使用@Qualifier
@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Beanpublic UserInfo userInfoL(){UserInfo userInfo = new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("123456");return userInfo;}}@Controller
public class TestController {@Qualifier("userInfoZ")@Autowiredprivate UserInfo userInfo;public void doController(){System.out.println(userInfo); //zhangsan}
}
  1. 使用@Resource
@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Beanpublic UserInfo userInfoW(String nameW){UserInfo userInfo = new UserInfo();userInfo.setUsername(nameW);userInfo.setPassword("123456");return userInfo;}@Beanpublic String nameW(){return "wangwu";}}@Controller
public class TestController {@Resource(name = "userInfoW")@Autowiredprivate UserInfo userInfo;public void doController(){System.out.println(userInfo);  //wangwu}
}
  1. 重命名Bean
@Configuration
public class BeanConfig {@Bean("u1")public UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Beanpublic UserInfo userInfoL(){UserInfo userInfo = new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("123456");return userInfo;}}@Controller
public class TestController {@Autowiredprivate UserInfo u1;public void doController(){System.out.println(u1); //zhangsan}
}

2.2 构造方法注入

  1. 构造函数的创建问题
    • 当我们新增了属性时,可能就要去新加上构造方法,十分繁琐
    • 当我们添加了有参的构造函数,就不会默认生成无参的构造函数了,如果需要用无参的,就需要手动生成
  2. @Autowired 指定用哪个构造函数:当有多个构造函数且没有指定用哪个时,Spring去初始化就会不知道用哪个,可能会报错
    • 如果有无参构造函数,默认用无参的,此时userService为null
    • 如果没有无参构造函数,我们需要用@Autowired告诉Spring使用哪个构造函数。当然,如果只有一个构造函数时,@Autowired是可以省略的
@Controller
public class TestController {private UserService userService;@Autowiredpublic TestController(UserService userService) {this.userService = userService;}public TestController() {}public void doController(){userService.doService();System.out.println("这是Controoler注解");}
}@Service
public class UserService {public void doService(){System.out.println("这是Service注解");}
}

2.3 setter方法注入

@Controller
public class TestController {private UserService userService;@Autowired    //需要加上,不加会报错public void setUserService(UserService userService) {this.userService = userService;}public void doController(){userService.doService();System.out.println("这是Controoler注解");}
}

2.4 三种注入方式优缺点分析

  1. 属性注入:虽然不被官方推荐,但因为简单,程序员推荐使用
    • 优点: 简洁,使用方便
    • 缺点:
      • @Autowired是Spring提供的,只能在Spring这使用
      • 不能注入⼀个Final修饰的属性
  2. 构造函数注⼊(Spring 4.X推荐)
    • 优点:
      • 符合final可以在构造方法中赋值的设定,故而可以注入final修饰的属性
      • 注入的对象不会被修改。因为构造函数是在创建对象的时候执行的,执行完之后除非再创建一个对象,或者使用Setter注入,否则不会轻易被改变。
      • 依赖对象在使用前⼀定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法
      • 通用性好, 构造方法是JDK支持的,即使是更换任何框架,他都是适用的
    • 缺点:注入多个对象时, 代码会比较繁琐,还需要用@Autowired指定
  3. Setter注入(Spring 3.X推荐):事实上,当一个对象需要被修改,我们就没必要交给Spring管理了,直接自己new一个算了
    • 优点:方便在类实例之后, 重新对该对象进行配置或者注入
    • 缺点:
      • 不能注入⼀个Final修饰的属性
      • 注入对象可能会被改变, 因为setter方法可能会被多次调用, 就有被修改的风险。你能改别人也能改,代码就会很乱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/15181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

以太坊钱包

以太坊钱包是你通往以太坊系统的门户。它拥有你的密钥,并且可以代表你创建和广播交易。选择一个以太坊钱包可能很困难,因为有很多不同功能和设计选择。有些更适合初学者,有些更适合专家。即使你现在选择一个你喜欢的,你可能会决定…

mac m1 pcre.h 找不到

安装suricata报错: configure: error: pcre.h not found ... 解决: brew install pcre 找到这个文件的地址 brew list pcre | grep pcre.h$ /opt/homebrew/Cellar/pcre/8.45/include/pcre.h 程序搜索的地址 cpp -v /Library/Developer/CommandLineT…

5.26 基于UDP的网络聊天室

需求&#xff1a; 如果有人发送消息&#xff0c;其他用户可以收到这个人的群聊信息 如果有人下线&#xff0c;其他用户可以收到这个人的下线信息 服务器可以发送系统信息实现模型 模型&#xff1a; 代码&#xff1a; //chatser.c -- 服务器端实现 #include <stdio.h>…

hive初始化失败报错:Error: Duplicate key name ‘PCS_STATS_IDX‘ (state=42000,code=1061)

意思是key name ‘PCS_STATS_IDX’ (state42000,code1061)重复了&#xff0c;问题出在不是第一次初始化&#xff0c;因为我们在hive-site.xml中配置了 javax.jdo.option.ConnectionURL jdbc:mysql://192.168.200.137:3306/metastore?createDatabaseIfNotExisttrue JDBC conne…

JavaSE——类和对象(二)~~封装

目录 一.封装 二.封装扩展之包 三.static成员 四. 代码块 五. 内部类&#xff08;重要&#xff09; 大家好呀&#xff0c;我是北纬&#xff0c;接着上节我们继续讲解Java中关于类和对象的相关知识&#xff0c;今天着重给大家介绍一下关于面向对象程序的特性之一——封装。…

【Linux】常用基础命令 | 搭建云服务器优化环境 | 程序的部署

文章目录 Linux常用命令及搭建环境一、LinuxLinux发行版 1.常用命令1.ls2.cd3.pwd4.touch5.cat6.echo7.vim8.mkdir9.rm10.mv11.cp12.man13.grep14.ps15.netstat 2.搭建Java Web程序的运行环境包管理器1.安装JDK2.安装Tomcat3.安装mysql 3.程序的部署 Linux常用命令及搭建环境 …

贪心算法简单介绍

贪心算法是一种在每一步选择中都采取当前状态下最优或最优近似的选择&#xff0c;以期望最终得到全局最优解的算法。贪心算法并不总能得到全局最优解&#xff0c;但在某些问题上&#xff0c;它可以得到全局最优解&#xff0c;并且比动态规划等其他方法更为简单和高效。 贪心算…

Python库之Scrapy的简介、安装、使用方法详细攻略

Python库之Scrapy的简介、安装、使用方法详细攻略 简介 Scrapy是一个快速的、高层次的web抓取和web抓取框架&#xff0c;用于抓取网站数据并从页面中提取结构化的数据。Scrapy用途广泛&#xff0c;可以用于数据挖掘、信息处理或存储历史数据&#xff0c;以及各种其他用途。 …

【AMS】Android 8.0+ 绕开启动后台Service限制

一、背景 应客户要求,需要在开机时,拉起应用A。但因为开机时,同时被拉起的应用过多,导致Launcher在开机那一刻较为卡顿。为解决这一问题,采取了延迟拉起的做法。在开机后,延迟一定时间,由系统服务,拉起应用A。 于是乎,就出现这么个报错: Not allowed to start ser…

vue3、vuex和vue-router入门指南

Vue 3、Vuex 和 Vue Router 都是 Vue.js 生态系统中非常有用的库。它们各自在 Vue.js 应用程序中扮演着重要的角色&#xff1a;Vue 3 是核心框架&#xff0c;Vuex 用于状态管理&#xff0c;而 Vue Router 用于路由管理。下面是如何在 Vue 3 项目中使用这些库的简要说明。 创建…

有趣的css - 移形换位加载动画

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是一个移形换位动态加载小动效&#xff0c;适用于 app 列表加载&#xff0c;页面加载或者图片懒加载等场景。 最新文章通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html…

2024上海初中生古诗文大会倒计时4个月:单选题真题解析(持续)

现在距离2024年初中生古诗文大会还有4个多月时间&#xff0c;我们继续来看10道选择题真题和详细解析&#xff0c;以下题目截取自我独家制作的在线真题集&#xff0c;都是来自于历届真题&#xff0c;去重、合并后&#xff0c;每道题都有参考答案和解析。 为帮助孩子自测和练习&…

C#基础一

使用Visual Studio 2022&#xff08;VS2022&#xff09;编写C#控制台程序 1. 安装Visual Studio 2022 确保已安装Visual Studio 2022。如果未安装&#xff0c;请从Visual Studio官网下载并安装。 另一篇文章中已经有详细描述&#xff0c;这里就不在细说了。 VisualStudio2022…

【LeetCode】【209】长度最小的子数组(1488字)

文章目录 [toc]题目描述样例输入输出与解释样例1样例2样例3 提示进阶Python实现前缀和二分查找滑动窗口 个人主页&#xff1a;丷从心 系列专栏&#xff1a;LeetCode 刷题指南&#xff1a;LeetCode刷题指南 题目描述 给定一个含有n个正整数的数组和一个正整数target找出该数组…

Effective C++(2)

文章目录 2. 构造、析构、赋值运算条款05&#xff1a;了解C默默编写并调用哪些函数条款06&#xff1a;若不想使用编译器自动生成的函数&#xff0c;就该明确拒绝条款07&#xff1a;为多态基类声明virtual析构函数条款08&#xff1a;别让异常逃离析构函数条款09&#xff1a;绝不…

微信小程序报错:notifyBLECharacteristicValueChange:fail:nodescriptor的解决办法

文章目录 一、发现问题二、分析问题二、解决问题 一、发现问题 微信小程序报错&#xff1a;notifyBLECharacteristicValueChange:fail:nodescriptor 二、分析问题 这个提示有点问题&#xff0c;应该是该Characteristic的Descriptor有问题&#xff0c;而不能说nodescriptor。 …

web前端之解决img元素组件自有高度的问题

MENU 前言解决办法vertical-align 前言 在HTML和CSS中&#xff0c;img元素默认是行内元素(inline element)&#xff0c;类似于文本。由于文本有基线(baseline)&#xff0c;所以即使是空白的img元素也会占据一定的高度&#xff0c;以便使基线对齐。 解决办法 要解决这个问题&…

axios如何传递数组作为参数,后端又如何接收呢????

前端的参数是一个数组。 前端编写&#xff1a; 后端接收&#xff1a;

Iterater迭代器和增强for循环

1、Collection接口遍历元素—Iterator迭代器 看一下下面这张图片&#xff1a;可以看出Collection接口有一个父接口Iterable&#xff0c;Iterable接口有一个iterator()方法&#xff0c;iterator()方法的类型是Iterator迭代器&#xff0c;实际上当我们使用方法时&#xff0c;返回…

Go语言的pprof工具是如何使用的?

文章目录 Go语言的pprof工具详解pprof的使用runtime/pprofnet/http/pprof 快速开始获取采样数据通过pprof工具进行性能分析总结 Go语言的pprof工具详解 Go语言作为一个高性能、高并发的编程语言&#xff0c;对性能优化有着极高的要求。在Go语言的标准库中&#xff0c;pprof是一…