• Spring 依赖注入


    目录

    2.更加简单的获取 Bean

    2.1 属性注入

    2.1.1 属性注入优点

    2.1.2 属性注入缺点

    2.2 Setter 注入

    2.2.1 优点

    2.2.2 缺点

    2.3 构造方法注入

    2.3.1 优点

    2.3.2 缺点

    2.4 @Resource:另⼀种注入关键字

    2.4.1 @Autowired VS @Resource 区别

    3.专项训练


    2.更加简单的获取 Bean

    获取 Bean 对象也叫做 对象装配,是把对象取出来放在某个类中,有时候也叫 对象注入

    对象装配(对象注入)的实现3种方式:

    1️⃣属性注入

    2️⃣构造方法注入

    3️⃣Setter 注入

    2.1 属性注入

    使用 @Autowired 实现:首先先根据 getTyoe (从容器中)获取对象,如果只获取一个,那么直接将此对象注入到当前属性上;如果获取多个对象,才会使用 getName (根据名称)进行匹配

    1️⃣例如,将 UserRepository 类注入到 UserService 类中:

    UserService 类的实现代码如下:

    1. package com.java.demo.service;
    2. import com.java.demo.dao.UserRepository;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.stereotype.Service;
    5. /**
    6. * Created with IntelliJ IDEA.
    7. * Description:
    8. * User: WJZ
    9. * Date: 2023-10-16
    10. * Time: 11:33
    11. */
    12. @Service
    13. public class UserService {
    14. //1.属性注解
    15. @Autowired //DI(依赖注入)
    16. private UserRepository userRepository;//从spring当中取到UserRepository,并把它设值给当前变量
    17. public int add() {
    18. System.out.println("Do UserService add method");
    19. //传统写法
    20. //UserRepository userRepository = new UserRepository();
    21. //return userRepository.add();
    22. //spring V1.0
    23. /*ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    24. UserRepository userRepository = context.getBean("userRepository",UserRepository.class);
    25. return userRepository.add();*/
    26. //spring V2.0
    27. return userRepository.add();
    28. }
    29. }

    UserRepository 类的实现代码如下:

    1. @Repository
    2. public class UserRepository {
    3. public int add() {
    4. System.out.println("Do UserRepository add method ");
    5. return 1;
    6. }
    7. }

    获取 UserService 中的 getUser ⽅法:

    1. class UserServiceTest {
    2. @Test
    3. void add() {
    4. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    5. UserService userService = context.getBean("userService", UserService.class);
    6. userService.add();
    7. }
    8. }

    2️⃣获取多个对象:

    User 类的实现代码如下:

    1. public class User {
    2. private String name;
    3. @Override
    4. public String toString() {
    5. return "User{" +
    6. "name='" + name + '\'' +
    7. '}';
    8. }
    9. public String getName() {
    10. return name;
    11. }
    12. public void setName(String name) {
    13. this.name = name;
    14. }
    15. }

    将 User 对象存储到 Spring当中:

    1. @Component
    2. public class Users {
    3. @Bean("user1")
    4. public User user1() {
    5. User user = new User();
    6. user.setName("张三");
    7. return user;
    8. }
    9. @Bean("user2")
    10. public User user2() {
    11. User user = new User();
    12. user.setName("李四");
    13. return user;
    14. }
    15. }

    在 UserService2 中调用 User 对象(这个对象相同类型存储到 spring 中有两个,则根据 getName (根据名称)进行匹配

    1. @Service
    2. public class UserService2 {
    3. //属性注入
    4. @Autowired
    5. private User user;
    6. public void sayHi() {
    7. System.out.println(user.toString());
    8. }
    9. }

    生成 UserService2Test 单元测试:

    1. class UserService2Test {
    2. @Test
    3. void sayHi() {
    4. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    5. UserService2 userService2 = context.getBean("userService2", UserService2.class);
    6. userService2.sayHi();
    7. }
    8. }

    上述代码含义:在 @Autowired 中注入 User 对象:User对象放在 Users 当中,Users 存放在 demo 包下,会随着 spring 启动而启动,也就是说 spring 启动的时候,就会在 spring 框架中存 user1 = 张三 和use2 = 李四 (类型都是 User),通过单元测试拿到 UserService2,在UserService2 中注入 User 对象,打印信息

    执行 测试类:

    获取报错:获取唯一一个bean,但是找到了两个 bean

    解决方案:

    1️⃣将属性的名字和 Bean 的名字对应上

    2️⃣使用 @Autowired 配合 @Qualifier 一起使用

    3️⃣使用 @Resource

    2.1.1 属性注入优点

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

    2.1.2 属性注入缺点

    1️⃣无法注入 final 修饰的变量

    final 特征

    • 被 final 修饰的变量需要直接赋值

    • 在构造方法中进行赋值

    2️⃣通用性问题:只适用于 IoC 容器

    3️⃣更容易违背单一设计原则,因为使用起来比较简单

    2.2 Setter 注入

    1. //Setter 注入
    2. @Service
    3. public class UserService3 {
    4. private UserRepository userRepository;
    5. @Autowired
    6. public void setUserRepository(UserRepository userRepository) {
    7. this.userRepository = userRepository;
    8. }
    9. public void sayHi() {
    10. System.out.println("Do UserService3 sayHi method");
    11. userRepository.add();
    12. }
    13. }

    2.2.1 优点

    通常 Setter 只 Set 一个书属性,所以 Setter 注入更符合单一设计原则

    2.2.2 缺点

    1️⃣无法注入 final 修饰的变量

    2️⃣setter 注入的对象可以被修改(setter 本来就是一个方法,有可能被多次调用和修改)

    2.3 构造方法注入

    造方法注入是 Spring 官方从 4.x 之后推荐的注入方式

    1. @Service
    2. public class UserService4 {
    3. private UserRepository userRepository;
    4. @Autowired
    5. public UserService4(UserRepository userRepository) {
    6. this.userRepository = userRepository;
    7. }
    8. public void sayHi() {
    9. System.out.println("Do UserService4 sayHi");
    10. userRepository.add();
    11. }
    12. }

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

    2.3.1 优点

    1️⃣可以注入 final 修饰的变量

    2️⃣注入的对象是不会被修改(因为构造方法只会加载一次)

    3️⃣构造方法注入可以保证注入对象完全初始化

    4️⃣构造方法注入通用性更好

    2.3.2 缺点

    1️⃣写法比属性注入复杂

    2️⃣使用构造方法注入,无法解决循环依赖的问题

    2.4 @Resource:另⼀种注入关键字

    在进⾏类注入时,除了可以使用 @Autowired 关键字之外,我们还可以使用 @Resource 进行注入

    2.4.1 @Autowired VS @Resource 区别

    1️⃣出身不同:@Resource 来自于JDK;@Autowired 来自于 Spring 框架

    2️⃣支持的参数不同:@Resource 支持很多参数设;@Autowired 只支持一个参数设置(@Qualifier)

    3️⃣使用区别:@Resource 不支持构造方法注入;而 @Autowired 支持构造方法注入

    4️⃣idea 兼容性支持不同:使用 @Autowired 在 idea 专业版可能会报错;@Resource 不存在误报的问题

    @Autowired来自于 spring,spring 框架是在程序执行之后再执行,不能检测到当前类是否注入(注入是的到 spring 当中)

    @Resource:java代码是在程序执行之前执行的,能检测到已经注入

    例如:我在开直播,有人先进来可以听到我之前讲的知识,有人后来就听不到我之前讲的知识,但是对于这个知识我已经讲过了,这个知识点是存在的。

    3.专项训练

    在 Spring 项⽬中,通过 main ⽅法获取到 Controller 类,调⽤ Controller ⾥⾯通过注⼊的⽅式调⽤ Service 类,Service 再通过注⼊的⽅式获取到 Repository 类,  类⾥⾯有⼀个⽅法构建⼀个 User 对象,返回给 main ⽅法。Repository ⽆需连接数据库,使⽤伪代码即

    创建 Maven项目,添加依赖pom.xml:

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframeworkgroupId>
    4. <artifactId>spring-beansartifactId>
    5. <version>5.2.3.RELEASEversion>
    6. dependency>
    7. <dependency>
    8. <groupId>org.springframeworkgroupId>
    9. <artifactId>spring-contextartifactId>
    10. <version>5.2.3.RELEASEversion>
    11. dependency>
    12. dependencies>

    新建 spring 配置文件spring-config.xml:

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:content="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    6. <content:component-scan base-package="spring.java.demo">content:component-scan>
    7. beans>

    新建目录 spring.java.demo:

    在新建 repository.UserRepository 类之前需要有一个 User 对象,新建 model.User 类:

    1. public class User {
    2. private int id;
    3. private String name;
    4. @Override
    5. public String toString() {
    6. return "User{" +
    7. "id=" + id +
    8. ", name='" + name + '\'' +
    9. '}';
    10. }
    11. public int getId() {
    12. return id;
    13. }
    14. public void setId(int id) {
    15. this.id = id;
    16. }
    17. public String getName() {
    18. return name;
    19. }
    20. public void setName(String name) {
    21. this.name = name;
    22. }
    23. }

    新建 repository.UserRepository 类:

    1. @Repository
    2. public class UserRepository {
    3. public User getUser() {
    4. User user = new User();
    5. user.setId(1);
    6. user.setName("张三");
    7. return user;
    8. }
    9. }

    新建 service.UserService 类(只是业务组装):

    1. @Service
    2. public class UserService {
    3. @Autowired
    4. private UserRepository userRepository;
    5. public User getUser() {
    6. return userRepository.getUser();
    7. }
    8. }

    新建 controller.UserController 类:

    1. @Controller
    2. public class UserController {
    3. @Autowired
    4. private UserService userService;
    5. public User getUser() {
    6. return userService.getUser();
    7. }
    8. }

    全局类(启动类)User:

    1. /**
    2. * 启动类
    3. */
    4. public class App {
    5. public static void main(String[] args) {
    6. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    7. UserController userController = context.getBean("userController", UserController.class);
    8. System.out.println(userController.getUser());
    9. }
    10. }

  • 相关阅读:
    贪心(5)
    SpringBoot整合RabbitMQ
    万界星空科技MES系统中的车间管理的作用
    第四章:串(KMP算法和KMP优化)
    Unity编辑器扩展
    国产AI网址
    BBR 会取代 CUBIC 吗?
    使用apriltag_ros检测相机姿态
    ODrive移植keil(六)—— 测量电阻电感和电流环PI参数整定
    Java代理
  • 原文地址:https://blog.csdn.net/m0_72161237/article/details/133855949