IoC / DI 实操

1. 建三层类

包结构:

com.lib  ├─ config  ├─ controller  ├─ service  ├─ repository  ├─ model  └─ annotation   // 自定义限定符
① 实体 Book
package com.lib.model;
public class Book {private Integer id;private String title;// 全参构造 + getter/setter/toString 省略
}
② Repository 接口
package com.lib.repository;
public interface BookRepository {Book findById(int id);
}
③ Repository 实现
package com.lib.repository;
@Repository
public class InMemoryBookRepository implements BookRepository {private Map<Integer, Book> store = new ConcurrentHashMap<>();public InMemoryBookRepository() {store.put(1, new Book(1, "Spring in Action"));}@Overridepublic Book findById(int id) {return store.get(id);}
}
④ Service
package com.lib.service;
@Service
public class BookService {private final BookRepository repo;   // ① 构造器注入@Autowiredpublic BookService(BookRepository repo) {this.repo = repo;}public Book query(int id) {return repo.findById(id);}
}
⑤ Controller
package com.lib.controller;
@Controller
@RequestMapping("/book")
public class BookController {private BookService bookService;   // ② 字段注入(演示用)@Autowiredpublic void setBookService(BookService bookService) {this.bookService = bookService; // ③ Setter 注入}@GetMapping("/{id}")@ResponseBodypublic Book get(@PathVariable int id) {return bookService.query(id);}
}

2. 三种注入方式对比

方式写法备注
构造器@Autowired 全参构造不可变、易测试
Setter@Autowired setXxx允许后期重配置
字段直接 @Autowired单元测试需反射

验证
浏览器访问 http://localhost:8080/library/book/1 → 返回 JSON
{"id":1,"title":"Spring in Action"} 即注入成功。


3. Bean 作用域实验

InMemoryBookRepository 类上加:

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

写测试控制器:

@GetMapping("/repo")
@ResponseBody
public String repoScope() {return "repo hash=" + bookService.getRepoHash(); // 在 Service 里返回 repo.toString()
}

连续刷新页面:

  • singleton(默认)→ hash 不变

  • prototype → 每次 hash 变化


4. 生命周期回调(30 min)

① 让 Repository 实现 2 个接口
@Repository
public class InMemoryBookRepository implements BookRepository,InitializingBean, DisposableBean {@PostConstructpublic void init() {System.out.println("[@PostConstruct] repo init, store size=" + store.size());}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("[InitializingBean] afterPropertiesSet");}@PreDestroypublic void preDestroy() {System.out.println("[@PreDestroy] repo will destroy");}@Overridepublic void destroy() throws Exception {System.out.println("[DisposableBean] destroy");}
}
② 启动/关闭 Tomcat,观察控制台顺序:
[@PostConstruct] repo init...
[InitializingBean] afterPropertiesSet...
...
[@PreDestroy] repo will destroy...
[DisposableBean] destroy...

截图保存,生命周期七连击完成。


5. Environment & 外部化配置

① 新建 app.properties 放 classpath
library.default.book.id=99
library.default.book.title=Default Book
② 配置类
@Configuration
@PropertySource("classpath:app.properties")
public class AppConfig {@Beanpublic Book defaultBook(Environment env) {return new Book(env.getProperty("library.default.book.id", Integer.class),env.getProperty("library.default.book.title"));}
}
③ 验证
@Autowired
private Book defaultBook;   // 字段注入,仅演示
@GetMapping("/default")
@ResponseBody
public Book def() {return defaultBook;  // {"id":99,"title":"Default Book"}
}

8. 常见错误速查

异常原因解决
No qualifying bean of type 'BookRepository'忘记 @Repository加注解或 @ComponentScan
Bean instantiation failed: No default constructor自己写了带参构造却未 @Autowired补上构造器 @Autowired
@PreDestroy not called外部 Tomcat 强杀用 catalina stop 温和关闭

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

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

相关文章

AdsPower RPA 从excel中依次读取多个TikTok账号对多个TikTok账号目标发送信息

多个账号对多个目标发送子场景 B&#xff1a;多个账号向“不同的”目标循环发送&#xff08;最复杂的群发逻辑&#xff09;流程&#xff1a;Excel表中有一个“目标用户”列表。RPA流程会进行嵌套循环&#xff1a;外层循环&#xff1a;遍历Excel中的每一行数据&#xff08;即每一…

扩散模型进化史

一幅精美的图片&#xff0c;一段精彩的视频&#xff0c;可能始于一片纯粹的噪声。 2024年的计算机视觉顶会CVPR上&#xff0c;扩散模型成为绝对主角。从图像生成到视频理解&#xff0c;从超分辨率到3D建模&#xff0c;扩散模型正以惊人的速度重塑着AIGC&#xff08;AI生成内容&…

一次 Linux 高负载 (Load) 异常问题排查实录

一次 Linux 高负载&#xff08;Load&#xff09;异常排查实录一、背景及排查过程材料二、排查分析2.1Load 的真正含义2.2&#xff1a;确认异常进程2.3&#xff1a;线程卡在哪&#xff08;wchan&#xff09;2.4&#xff1a;perf 采样&#xff08;用户态/内核态热点&#xff09;2…

浅析Linux进程信号处理机制:基本原理及应用

文章目录概述信号类型可靠信号与不可靠信号Fatal信号与Non Fatal信号不可捕获/忽略信号信号工作机制信号处理方式信号嵌套处理信号使用信号发送kill命令注册信号处理函数信号安全与函数可重入性可重入函数线程安全与可重入性相关参考概述 Linux信号机制是进程间通信的一种方式…

【学习K230-例程19】GT6700-TCP-Client

B站视频 TCP TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff0c;传输控制协议/网际协议&#xff09;是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP 协议不仅仅指的是 TCP和 IP 两个协议&#xff0c;而是指一个由 FTP、SMTP、TCP、UDP、I…

o2oa待办流程和已办流程表

在o2oa系统中每个用户有两种唯一标识&#xff1a;第一种是姓名个人钉钉ID&#xff08;或者o2oa创建该用户时设置的id&#xff09;ORG_PERSON.xdistinguishedName刘准3013692136672430P第二种是姓名所在部门的钉钉id个人钉钉idORG_IDENTITY.xdistinguishedName刘准966488616_301…

QT零基础入门教程

基础篇第一章 QT 基础认知1.1 什么是 QT&#xff08;What&#xff09;​定义&#xff1a;跨平台 C 应用开发框架&#xff0c;不仅用于 UI 设计&#xff0c;还包含核心功能&#xff08;如事件、网络、数据库&#xff09;。​核心特性&#xff1a;​跨平台&#xff1a;一套代码支…

远程依赖管理新范式:cpolar赋能Nexus全球协作

文章目录 前言一. Docker安装Nexus二. 本地访问Nexus三. Linux安装Cpolar四. 配置Nexus界面公网地址五. 远程访问 Nexus界面六. 固定Nexus公网地址七. 固定地址访问Nexus 前言 Nexus作为一款企业级仓库管理工具&#xff0c;其核心功能在于集中管理各类软件依赖&#xff0c;提供…

Prompt技术深度解析:从基础原理到前沿应用的全面指南

引言 在人工智能技术飞速发展的今天&#xff0c;Prompt技术&#xff08;提示词工程&#xff09;已成为连接人类智慧与机器智能的重要桥梁。随着GPT-4、Claude、Gemini等大型语言模型的广泛应用&#xff0c;如何有效地与这些AI系统进行交互&#xff0c;已成为决定AI应用成功与否…

性能测试工具Jmeter之java.net.BindException: Address already in use

首先请参考连接&#xff1a;https://blog.csdn.net/weixin_46190208/article/details/115229733 。配置完注册表后一般就能解决问题。但并未解决我的问题 注册表的MaxUserPort&#xff0c;TcpTimedWaitDelay两个参数我只能配置MaxUserPort&#xff0c;设置TcpTimedWaitDelay后&…

JDK 新特性

JDK 新特性引入模块Java 9 开始引入了模块&#xff08;Module&#xff09;&#xff0c;目的是为了管理依赖。使用模块可以按需打包 JRE 和进一步限制类的访问权限。接口支持私有方法JAVA 9 开始&#xff0c;接口里可以添加私有方法&#xff0c;JAVA 8 对接口增加了默认方法的支…

如何高效应对网站反爬虫策略?

现在大型网站的反爬策略越来越高明了&#xff0c;不仅是对IP访问频率、User-Agent请求头进行异常识别&#xff0c;还会分析IP地址、浏览器指纹、JS动态加载、API逆向、行为模式等方式各种设卡&#xff0c;动不动跳出五花八门的验证码&#xff0c;非常难搞。 怎么应对反爬是个系…

c++ shared_ptr理解

不是一个智能指针对于一个计数器吗&#xff1f;怎么变成共有资源的计数器了&#xff1f;你的意思是多个对象共用一个计数器&#xff1f;你问到了 std::shared_ptr 最核心、最精妙的设计机制&#xff01;你的问题非常深刻&#xff1a;“不是一个智能指针对应一个计数器吗&#x…

002 Rust环境搭建

Rust环境搭建 现在很多集成开发环境(IDE)基本上都支持Rust开发。官方公布的支持工具&#xff1a;https://www.rust-lang.org/zh-CN/tools 这里以Windows 10 64位系统 Visual Studio Code为例来搭建Rust开发环境。 Rust安装 Rust 的编译工具依赖 C 语言的编译工具&#xff0…

【Unity进阶】Unity发布PC端,隐藏并自定义默认标题栏

开发环境&#xff1a; Unity2019.3.16f1c1 - 个人版 Visual Studio Community 2019 Windows10 专业版 x64嘿&#xff0c;各位朋友们&#xff01;当咱们欢欢喜喜地把项目打包成PC平台的exe窗口程序&#xff0c;准备在电脑上一展游戏风采时&#xff0c;却发现冒出来个Windows风格…

国产延时芯片EH3B05上电延时3秒开关机芯片方案超低功耗

EH3B05-4941-24A1延时开关芯片是一款专为低功耗电子产品设计的高效时序控制器件&#xff0c;其核心功能在于提供精确的多通道延时信号输出。该芯片采用SOT23-6超小封装&#xff0c;体积仅为2.9mm2.8mm1.3mm&#xff0c;特别适合空间受限的便携式设备。其工作电压范围覆盖2.0V至…

大数据与财务管理专业如何转型做金融科技?

在数字经济加速演进的今天&#xff0c;金融行业的边界正在被数据与技术重新定义。传统金融岗位正经历深刻变革&#xff0c;而"金融科技"&#xff08;FinTech&#xff09;作为技术与金融深度融合的产物&#xff0c;已成为行业转型升级的核心引擎。越来越多具备数据背景…

Windows、Linux 系统 nodejs 和 npm 版本更新及错误修复

一、推荐使用 nvm 工具&#xff0c;直接通过命令行安转和切换各个版本 无论是 Windows 平台&#xff0c;还是 Linux 平台&#xff0c;都推荐使用 nvm 工具。 nvm&#xff08;Node.js Version Management&#xff09;&#xff0c;是一个 nodejs 的版本管理工具。它是专门为解决…

【系列文章】Linux中的并发与竞争[03]-自旋锁

【系列文章】Linux中的并发与竞争[03]-自旋锁 该文章为系列文章&#xff1a;Linux中的并发与竞争中的第3篇 该系列的导航页连接&#xff1a; 【系列文章】Linux中的并发与竞争-导航页 文章目录【系列文章】Linux中的并发与竞争[03]-自旋锁一、自旋锁二、实验程序的编写2.1驱动…

开始 ComfyUI 的 AI 绘图之旅-Cosmos Predict2世界模型文生图(全网首发,官网都没有更新)(十三)

文章标题一、Cosmos-Predict21.Cosmos Predict2 Text2Image 工作流1.1 下载工作流文件1.2 手动模型安装1.3 按步骤完成工作流运行本文介绍了如何在 ComfyUI 中完成 Cosmos-Predict2 文生图的工作流 一、Cosmos-Predict2 Cosmos-Predict2 是由 NVIDIA 推出的新一代物理世界基础模…