新闻详情

新闻详情

首页 / 资讯中心 / 详情

Spring DI 详解

发布时间:2026/11/12 14:40:39来源:尧图网络
Spring DI 详解
学习过 IoC 后就知道我们可以将对象交给 Spring 进行管理但是我们在一个类会有若干属性也就是这个类依赖于这若干个属性那么我们就可以将交给 Spring 管理的对象注入到这个类中这也就是依赖注入。依赖注入有三种方式分别为属性注入、构造方法注入、setter方法注入。下面一一介绍。一、属性注入Autowired有如下代码Controller public class TestController { //属性注入 Autowired private TestService service; public void print() { System.out.println(controller); service.print(); } } Service public class TestService { public void print() { System.out.println(service); } } //SpringBoot 启动类 SpringBootApplication public class SpringBootDemo2025417Application { public static void main(String[] args) { ApplicationContext context SpringApplication.run(SpringBootDemo2025417Application.class, args); //获取 TestController 对象 TestController controller context.getBean(TestController.class); controller.print(); } }在 TestController 类中有属性 service我们通过 Autowired 注解将 TestService 输入到属性 service 中这样我们就可以使用 TestService 中的相关方法了代码运行结果如下代码先执行了 TestController 的print 方法然后又执行了 TestService 的 print 方法。现有下面两种情况一种没加 Service另一种是没加 Autowired下面我们来分别看看这两种情况。没加 Service运行代码后发现报错了错误代码如下Description: Field service in com.gjm.demo.controller.TestController required a bean of type com.gjm.demo.service.TestService that could not be found.由于我们没有加 Service就代表我们没有将 TestService 类交给 Spring 进行管理那么我们在使用 Autowired 在 Spring 容器中获取对象时就找不到这个对象就会报这个错。没加 Autowired运行代码后发现报错了错误代码如下controller Exception in thread main java.lang.NullPointerException: Cannot invoke com.gjm.demo.service.TestService.print() because this.service is null at com.gjm.demo.controller.TestController.print(TestController.java:16) at com.gjm.demo.SpringBootDemo2025417Application.main(SpringBootDemo2025417Application.java:19)我们发现了这里报了一个空指针异常这时为什么呢原因是虽然我们加了 Service 注解将 TestService 交给 Spring 进行管理但是由于我们没有加 Autowired 注解就使得我们并没有将 TestService 的对象注入给 service也即是并没有初始化 service当我们在吊桶TestService 的 print 方法时就会报空指针异常。这也就是 “controller” 可以显示出来但 “service” 显示不出来的原因。二、构造方法注入顾名思义就是将属性放到构造方法中在进行注入代码如下Controller public class TestController { private TestService service; //构造方法 public TestController(TestService service) { this.service service; } public void print() { System.out.println(controller); service.print(); } } Service public class TestService { public void print() { System.out.println(service); } } SpringBootApplication public class SpringBootDemo2025417Application { public static void main(String[] args) { ApplicationContext context SpringApplication.run(SpringBootDemo2025417Application.class, args); //获取 TestController 对象 TestController controller context.getBean(TestController.class); controller.print(); } }代码运行结果如下在上面的构造方法中没有加任何注解就将 TestService 注入给了 TestController。但在日常开发中加上了有参的构造函数无参的构造函数就默认没有了为了避免出现问题我们还会将无参的构造函数也加上代码如下Controller public class TestController { private TestService service; //无参构造函数 public TestController() { } //有参构造函数 public TestController(TestService service) { this.service service; } public void print() { System.out.println(controller); service.print(); } }代码运行结果如下controller Exception in thread main java.lang.NullPointerException: Cannot invoke com.gjm.demo.service.TestService.print() because this.service is null at com.gjm.demo.controller.TestController.print(TestController.java:27) at com.gjm.demo.SpringBootDemo2025417Application.main(SpringBootDemo2025417Application.java:19)又报错了 是空指针异常。这是因为我们加上了无参的构造函数在进行构造方法注入的时候默认的构造方法为无参的构造方法若没有无参的给构造方法就会使用我们自己写的构造方法。这里我们把无参的构造方法加上了就会使用无参的构造方法这时就不会给 service 进行注入也就是 service 没有进行初始化在调用 print 方法时就会出现空指针异常。上面时只有一个属性的情况那如果 testController 中有多个属性呢下面我们介绍有两个属性的情况。代码如下package com.gjm.demo.controller; import com.gjm.demo.service.TestService1; import com.gjm.demo.service.TestService2; import org.springframework.stereotype.Controller; Controller public class TestController { private TestService1 service1; private TestService2 service2; public TestController() { } public TestController(TestService1 service1) { this.service1 service1; } public TestController(TestService2 service2) { this.service2 service2; } public TestController(TestService1 service1, TestService2 service2) { this.service1 service1; this.service2 service2; } public void print() { System.out.println(controller); service1.print(); service2.print(); } } Service public class TestService1 { public void print() { System.out.println(service1); } } Service public class TestService2 { public void print() { System.out.println(service2); } } SpringBootApplication public class SpringBootDemo2025417Application { public static void main(String[] args) { ApplicationContext context SpringApplication.run(SpringBootDemo2025417Application.class, args); //获取 TestController 对象 TestController controller context.getBean(TestController.class); controller.print(); } }在 TestController 中有两个属性分别为 TestService1 和 TestService2代码运行结果如下controller Exception in thread main java.lang.NullPointerException: Cannot invoke com.gjm.demo.service.TestService1.print() because this.service1 is null at com.gjm.demo.controller.TestController.print(TestController.java:49) at com.gjm.demo.SpringBootDemo2025417Application.main(SpringBootDemo2025417Application.java:17)发现这个报错信息与前一个报错信息是一样的也是空指针异常。这是因为无论有几个属性构造方法注入的默认构造方法都是无参构造方法就相当于 service1 和 service2 书香都没有初始化在调用 print 方法就会报空指针异常。那如果将无参的构造方法去掉呢代码如下package com.gjm.demo.controller; import com.gjm.demo.service.TestService1; import com.gjm.demo.service.TestService2; import org.springframework.stereotype.Controller; Controller public class TestController { private TestService1 service1; private TestService2 service2; public TestController(TestService1 service1) { this.service1 service1; } public TestController(TestService2 service2) { this.service2 service2; } public TestController(TestService1 service1, TestService2 service2) { this.service1 service1; this.service2 service2; } public void print() { System.out.println(controller); service1.print(); service2.print(); } }代码运行结果如下controller Exception in thread main java.lang.NullPointerException: Cannot invoke com.gjm.demo.service.TestService1.print() because this.service1 is null at com.gjm.demo.controller.TestController.print(TestController.java:49) at com.gjm.demo.SpringBootDemo2025417Application.main(SpringBootDemo2025417Application.java:17)同样的也是空指针异常那应该怎么办呢在构造方法注入中也可以使用 Autowired 注解当在构造方法上使用该注解时表示的含义就是修改默认的构造函数于是可以在全参的构造函数上加上 Autowired 注解代码如下package com.gjm.demo.controller; import com.gjm.demo.service.TestService1; import com.gjm.demo.service.TestService2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; Controller public class TestController { private TestService1 service1; private TestService2 service2; public TestController() { } public TestController(TestService1 service1) { this.service1 service1; } public TestController(TestService2 service2) { this.service2 service2; } Autowired public TestController(TestService1 service1, TestService2 service2) { this.service1 service1; this.service2 service2; } public void print() { System.out.println(controller); service1.print(); service2.print(); } }运行结果如下这次就运行成功了。三、setter 方法注入setter 方法注入即使用 setter方法进行属性注入在使用时需要在对应的 setter 方法上加上 Autowired 注解如果不加就会报错。代码如下package com.gjm.demo.controller; import com.gjm.demo.service.TestService1; import com.gjm.demo.service.TestService2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; Controller public class TestController { private TestService1 service1; private TestService2 service2; Autowired public void setService1(TestService1 service1) { this.service1 service1; } Autowired public void setService2(TestService2 service2) { this.service2 service2; } public void print() { System.out.println(controller); service1.print(); service2.print(); } } Service public class TestService1 { public void print() { System.out.println(service1); } } Service public class TestService2 { public void print() { System.out.println(service2); } } SpringBootApplication public class SpringBootDemo2025417Application { public static void main(String[] args) { ApplicationContext context SpringApplication.run(SpringBootDemo2025417Application.class, args); //获取 TestController 对象 TestController controller context.getBean(TestController.class); controller.print(); } }运行结果如下
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/11 13:52:51

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/10 19:42:40

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/12 9:50:02

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/12 9:25:38

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/11 15:37:39

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/10 17:14:10

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉