【JavaEE进阶】Spring DI

news/2025/2/24 5:50:32

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗

如有错误,欢迎指出~


依赖注⼊是⼀个过程,是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源,⽽资源指的就是对象. 在上⾯程序案例中,我们使⽤了 @Autowired 这个注解,完成了依赖注⼊的操作. 简单来说,就是把对象取出来放到某个类的属性中.

注入方式

关于依赖注⼊,Spring也给我们提供了三种⽅式:

1. 属性注⼊(FieldInjection)

2. 构造⽅法注⼊(ConstructorInjection)

3. Setter注⼊(SetterInjection)

属性注⼊

属性注⼊是使⽤@Autowired 实现的,将Service类注⼊到Controller类中. Service类的实现代码如下:

@Service

public class UserService {
    public void sayHi(){
        System.out.println("hi,UserService..." );
    }

}
@Controller // 将对象存储到 Spring 中
public class UserController {
    @Autowired
    private UserService service;

    public void sayHi(){
        System.out.println("hi,UserController...");
        service.sayHi();
    }
}

 构造⽅法注⼊

构造⽅法注⼊是在类的构造⽅法中实现注⼊,如下代码所⽰:



@Controller // 将对象存储到 Spring 中
public class UserController {
    private UserService service;
    @Autowired
    public UserController(UserService userService){
        this.service = userService;
    }
    public void sayHi(){
        System.out.println("hi,UserController...");
        service.sayHi();
    }
}

注意事项:如果类只有⼀个构造⽅法,那么@Autowired注解可以省略;如果类中有多个构造⽅法, 那么需要添加上@Autowired来明确指定到底使⽤哪个构造⽅法。

Setter注⼊

Setter注⼊和属性的Setter⽅法实现类似,只不过在设置set⽅法的时候需要加上@Autowired注 解,如下代码所⽰:

@Controller // 将对象存储到 Spring 中
public class UserController {
    private UserService service;
    @Autowired
    public void setService(UserService userService){
        this.service = userService;
    }
    public void sayHi(){
        System.out.println("hi,UserController...");
        service.sayHi();
    }
}

三种注⼊优缺点分析

  • 属性注⼊ ◦
    • 优点: 简洁,使⽤⽅便
    • 缺点:
      • 只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指 针异常)
      • 不能注⼊⼀个Final修饰的属性
  • 构造函数注⼊(Spring4.X推荐)
    • 优点:
      • 可以注⼊final修饰的属性
      • 注⼊的对象不会被修改
      • 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法 是在类加载阶段就会执⾏的⽅法.
      • 通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的
    • 缺点: 注⼊多个对象时,代码会⽐较繁琐
  • Setter注⼊(Spring3.X推荐)
    • 优点:⽅便在类实例之后,重新对该对象进⾏配置或者注⼊
    • 缺点:
      • 不能注⼊⼀个Final修饰的属性
      • 注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的⻛险.

@Autowired存在问题

当同⼀类型存在多个bean时,使⽤@Autowired会存在问题

@Component//@Bean要配合类注解使用
public class BeanConfig {
    @Bean
    public User user1(){
        User user = new User();
        user.setName("zhangsan");
        user.setAge(18);
        user.setGender("男");
        return user;
    }

    @Bean
    public User user2(){
        User user = new User();
        user.setName("lisi");
        user.setAge(81);
        user.setGender("女");
        return user;
    }
}
@Controller // 将对象存储到 Spring 中
public class UserController {
    //注⼊user
    @Autowired
    private User user;

    public void sayHi(){
        System.out.println("hi,UserController...");
        System.out.println(user);
    }
}

报错的原因是,⾮唯⼀的Bean对象。

解决方案

Spring提供了以下⼏种解决⽅案:

  1. @Primary :当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现.
  2. @Qualifier : 指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean 的名称。@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤
  3. @Resource: 按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称

代码示例 

@Primary

@Component
public class BeanConfig {

    @Primary
    @Bean
    public User user1(){
        ...
    }

    @Bean
    public User user2(){
        ...
    }
}

 @Qualifier

@Controller
public class UserController {

    //注⼊user
    @Autowired
    @Qualifier("user2")
    private User user;

    public void sayHi(){
        System.out.println("hi,UserController...");
        System.out.println(user);
    }
}

@Resource

@Controller 
public class UserController {

    //注⼊user
    @Resource(name = "user2")
    private User user;

    public void sayHi(){
        System.out.println("hi,UserController...");
        System.out.println(user);
    }
}

常⻅⾯试题:@Autowird与@Resource的区别

  1. @Autowired是spring框架提供的注解,⽽@Resource是JDK提供的注解
  2. @Autowired默认是按照类型注⼊,⽽@Resource是按照名称注⼊.相⽐于@Autowired来说, @Resource⽀持更多的参数设置,例如name设置,根据名称获取Bean.


http://www.niftyadmin.cn/n/5863998.html

相关文章

libwebsockets交叉编译全流程

libwebsocket中的webscoket加密功能需要依赖于Openssl库因此需要提前准备好openssl开源库。 交叉编译openssl 下面演示源码方式交叉编译OpenSSL为动态库。 创建个Websocket文件夹,把后续的成果物均放在这个文件中,文件夹中创建子文件夹OpenSSL和libWeb…

TIKTOK矩阵系统的软件服务

TikTok矩阵系统的技术服务概述 随着TikTok平台的发展,越来越多的内容创作者和企业选择通过矩阵系统来优化他们的内容管理和推广。TikTok矩阵系统是一种旨在高效管理多个账户、提升内容曝光、增强互动和加速推广的技术工具。以下是该系统提供的主要功能和技术服务&a…

jmeter 与大数据生态圈中的服务进行集成

以下为你详细介绍 JMeter 与大数据生态圈中几种常见服务(Hadoop HDFS、Spark、Kafka、Elasticsearch)集成的方法: 与 Hadoop HDFS 集成 实现思路 HDFS 是 Hadoop 的分布式文件系统,JMeter 可模拟客户端对 HDFS 进行文件读写操作…

云原生(五十七) | 阿里云CDN基本概念

文章目录 阿里云CDN基本概念 一、阿里云CDN概述 二、为什么选择阿里云CDN 三、阿里云CDN应用场景 四、总结 阿里云CDN基本概念 一、阿里云CDN概述 阿里云内容分发网络CDN是建立并覆盖在承载网之上,由遍布全球的边缘节点服务器群组成的分布式网络。阿 里云CDN…

Hadoop常用操作命令

在NameNode节点格式化集群 初始化集群 hdfs namenode -format启动HDFS sbin/start-dfs.sh启动yarn sbin/start-yarn.sh启动NodeManager yarn-daemon.sh start nodemanager启动DataNode hadoop-daemon.sh start datanode启动SecondaryNameNode hadoop-daemon.sh start se…

jmeter 接入deepseek 或者chatgpt

接入ChatGPT 实现思路 要将JMeter与ChatGPT接入,核心在于通过JMeter发送HTTP请求至OpenAI的API接口,以此调用ChatGPT进行交互。整个过程包含创建JMeter测试计划、添加必要组件、配置请求参数以及处理响应结果等步骤。 具体步骤 1. 获取OpenAI API密钥…

Android构建系统 - 01 环境准备

Android 构建系统的组成 Android构建系统由python,gn,ninja,makefile这几部分组成。 **python**∶做好编译前的准备工作和为 gn 收集命令参数。胶水语言,最擅长的是对参数,环境变量,文件操作。 gn∶类似构…

PyTorch 源码学习:GPU 内存管理之它山之石——TensorFlow BFC 算法

TensorFlow 和 PyTorch 都是常用的深度学习框架,各自有一套独特但又相似的 GPU 内存管理机制(BFC 算法)。它山之石可以攻玉。了解 TensorFlow 的 BFC 算法有助于学习 PyTorch 管理 GPU 内存的精妙之处。本文重点关注 TensorFlow BFC 算法的核…