当前位置: 首页 > article >正文

Spring IOC 注解进阶:@Bean 管理第三方 Bean,@Import 拆分配置,@Value 注入资源(Spring系列5)

在日常Spring开发中我们习惯用Component、Service、Repository这类注解标记自己编写的业务类让Spring自动扫描并纳入IOC容器管理。但如果是第三方Jar包中的类比如Druid数据源、第三方工具类我们无法修改源码添加注解这时候就需要用到Bean注解通过配置类灵活定义Bean。同时当项目规模扩大、Bean数量增多时我们还会遇到「配置类臃肿」「外部资源注入」「依赖其他Bean」等问题这就涉及到Import、Value、PropertySource等核心注解的实战应用。本文将从环境搭建到完整案例全面讲解这些注解的用法、原理、核心区别与最佳实践帮你彻底搞懂Spring第三方Bean管理的全流程。一、环境准备搭建基础Spring项目首先我们搭建一个基础的Spring项目为后续案例做准备1.1 创建Maven项目添加Spring依赖在pom.xml中引入Spring核心依赖dependencies dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.2.10.RELEASE/version /dependency /dependencies1.2 创建基础类与配置类1. 配置类SpringConfigSpring的核心配置类Configuration public class SpringConfig { }2. BookDao接口与实现类模拟业务类public interface BookDao { void save(); }Repository public class BookDaoImpl implements BookDao { Override public void save() { System.out.println(book dao save ...); } }3. 运行类App启动Spring容器public class App { public static void main(String[] args) { AnnotationConfigApplicationContext ctx new AnnotationConfigApplicationContext(SpringConfig.class); } }1.3 最终项目结构spring_14_annotation_third_bean_manager ├── src │ ├── main │ │ ├── java │ │ │ └── com.itheima │ │ │ ├── config │ │ │ │ └── SpringConfig.java │ │ │ ├── dao │ │ │ │ ├── BookDao.java │ │ │ │ └── impl │ │ │ │ └── BookDaoImpl.java │ │ │ └── App.java │ │ └── resources └── pom.xml二、Bean注解管理第三方Bean以Druid数据源为例2.1 Bean的作用与核心特点Bean是Spring提供的、用于在配置类中手动定义Bean的注解核心作用是标记在Configuration配置类的方法上告诉Spring「这个方法返回的对象交给Spring容器管理作为一个Bean」。加了Bean后Spring会调用该方法将返回的对象存入IOC容器后续其他Bean需要该类型的对象时直接从容器中注入即可。2.2 Bean vs Component 核心区别对比很多同学会混淆Bean和Component这里用表格清晰对比两者的差异对比维度BeanComponent含Service/Repository等使用位置配置类Configuration修饰的方法上自定义类的类上创建逻辑完全自定义可手动new对象、设置属性、复杂初始化Spring自动扫描默认通过无参构造创建适用场景整合第三方库、需要复杂初始化逻辑的Bean自己编写的普通业务类控制粒度方法级可灵活控制Bean的创建过程类级统一扫描管理是否依赖源码不需要修改第三方类源码必须在类上添加注解依赖源码2.3 完整实现步骤我们以Druid数据源为例演示如何用Bean管理第三方Bean步骤1导入Druid依赖在pom.xml中添加Druid的Maven依赖dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.1.16/version /dependency步骤2在配置类中定义Bean方法在SpringConfig中添加方法返回DruidDataSource对象并添加Bean注解Configuration public class SpringConfig { Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }⚠️ 注意不能直接用DataSource ds new DruidDataSource()因为DataSource接口中没有对应的setter方法必须使用具体实现类DruidDataSource来设置属性。步骤3从IOC容器中获取Bean并测试修改App类从容器中获取DataSource对象并打印public class App { public static void main(String[] args) { AnnotationConfigApplicationContext ctx new AnnotationConfigApplicationContext(SpringConfig.class); DataSource dataSource ctx.getBean(DataSource.class); System.out.println(dataSource); } }运行程序控制台会打印Druid数据源对象说明第三方Bean已经成功被Spring管理。三、配置类拆分ComponentScan vs Import 两种方案如果把所有Bean都写在SpringConfig中会导致配置类越来越臃肿不利于代码阅读和分类管理。因此我们可以按业务类别拆分配置类比如把数据源相关的Bean放到JdbcConfig中。3.1 方案一ComponentScan包扫描引入不推荐实现步骤1. 创建JdbcConfig配置类添加Configuration和Bean注解Configuration public class JdbcConfig { Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }2. 在SpringConfig中添加包扫描扫描JdbcConfig所在的包Configuration ComponentScan(com.itheima.config) public class SpringConfig { }3. 运行App类依然可以正常获取DataSource对象。缺点无法直观看到Spring加载了哪些配置类、全量扫描增加容器负担不推荐生产环境使用3.2 方案二Import手动指定引入推荐Import是Spring提供的、用于手动指定需要加载的配置类的注解完美解决了包扫描的痛点。实现步骤1. 移除JdbcConfig的Configuration注解public class JdbcConfig { Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }2. 在SpringConfig中添加Import注解手动导入JdbcConfigConfiguration Import({JdbcConfig.class}) public class SpringConfig { }3.3 Import核心原理与使用场景本质Spring默认通过ComponentScan扫描带有Configuration、Component的类纳入容器管理。而Import的核心功能是强制指定类纳入Spring容器无论该类是否有Configuration或其他组件注解。核心使用场景导入第三方库中的配置类精细化控制配置加载避免全量扫描结合Conditional实现条件化导入配置3.4 Import使用注意事项参数是数组支持导入多个配置类Import({JdbcConfig.class, XxxConfig.class})一个配置类中只能写一次Import不能多次添加可以完全替代ComponentScan提升容器启动效率四、Bean方法中注入资源简单数据类型引用数据类型在使用Bean创建Bean时方法中往往需要依赖其他资源分为两类简单数据类型比如字符串、数字和引用数据类型比如其他Bean。4.1 简单数据类型注入ValuePropertySource读取配置文件需求分析将数据库连接四要素硬编码提取到properties文件通过注解注入。1. 在resources目录下创建jdbc.properties配置文件jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/spring_db jdbc.usernameroot jdbc.passwordroot2. 在JdbcConfig中添加PropertySource注解加载配置文件PropertySource(classpath:jdbc.properties) public class JdbcConfig { // 注入配置文件中的值 Value(${jdbc.driver}) private String driver; Value(${jdbc.url}) private String url; Value(${jdbc.username}) private String userName; Value(${jdbc.password}) private String password;Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(userName); ds.setPassword(password); return ds; } }4.2 引用数据类型注入方法参数自动装配需求分析将BookDao对象注入到Bean方法中。1. 在SpringConfig中扫描BookDao所在的包Configuration ComponentScan(com.itheima.dao) Import({JdbcConfig.class}) public class SpringConfig { }2. 在JdbcConfig的dataSource方法中添加BookDao参数PropertySource(classpath:jdbc.properties)//这个注解建议放在主配置类SpringConfig上原因如下配置聚合主配置类是整个 Spring 环境的入口在这里统一管理所有配置扫描、导入、资源文件逻辑最完整。避免冗余如果以后还有其他配置类如 RedisConfig只需要在 SpringConfig里加一个PropertySource即可不需要每个配置类都写一遍。 public class JdbcConfig { Value(${jdbc.driver}) private String driver; Value(${jdbc.url}) private String url; Value(${jdbc.username}) private String userName; Value(${jdbc.password}) private String password;////不能在方法里定义BookDao bookDao用atuowired注解spring扫描不到。当 Bean 被初始化时Spring 会检查该 Bean 类的 类级别成员字段或 类级别的方法构造器、setter 等上的 Autowired并执行注入。 Bean public DataSource dataSource(BookDao bookDao){ System.out.println(bookDao); DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(userName); ds.setPassword(password); return ds; } }运行程序即可验证引用类型注入成功。五、总结与最佳实践核心知识点总结注解核心作用适用场景Bean在配置类方法上定义Bean管理第三方Bean、复杂初始化Import手动指定加载配置类拆分配置、导入第三方配置Value注入简单数据类型读取配置、注入常量PropertySource加载外部properties文件分离配置与代码最佳实践第三方Bean统一用Bean管理配置类按业务拆分用Import手动导入配置统一放到properties文件通过Value注入Bean方法依赖其他Bean时优先用方法参数注入减少ComponentScan范围提升容器启动效率

相关文章:

Spring IOC 注解进阶:@Bean 管理第三方 Bean,@Import 拆分配置,@Value 注入资源(Spring系列5)

在日常Spring开发中,我们习惯用Component、Service、Repository这类注解标记自己编写的业务类,让Spring自动扫描并纳入IOC容器管理。但如果是第三方Jar包中的类(比如Druid数据源、第三方工具类),我们无法修改源码添加注…...

如何评估网站SEO优化的合理价格

如何评估网站SEO优化的合理价格 在当今数字化时代,网站的SEO优化已经成为提升网站流量和品牌知名度的关键因素。很多人在考虑投入网站SEO优化的时候,往往对其合理价格感到困惑。如何评估网站SEO优化的合理价格呢?本文将从多个角度为你详细解…...

VCS编译优化全攻略:从-pcmakeprof时间分析到partition配置技巧

VCS编译优化全攻略:从-pcmakeprof时间分析到partition配置技巧 在芯片验证领域,编译时间直接影响着工程师的迭代效率。当RTL代码规模突破千万行时,一次完整编译可能消耗数小时,而传统增量编译往往因为细粒度不足导致不必要的重复工…...

linux——退出单一线程

pthread_exitexit(0)函数原型&#xff1a; void pthread‐exit(void *retval)&#xff1b; retval指针&#xff1a;必须指向全局&#xff0c;堆 #include<stdio.h> #include<pthread.h> #include<unistd.h> #include<string.h> #include<stdlib.h&…...

告别论文 “红标警告”!Paperxie 四大降重降 AIGC 功能:让本科生毕业通关率飙升

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/weight?type1https://www.paperxie.cn/weight?type1 一、 论文人的崩溃瞬间&#xff1a;查重红了&#xff0c;AIGC 标了&#xff0c;答辩悬了 你有没有过这样的经历&#…...

从 99.8% 到 14.9%!Paperxie 降重 / 降 AIGC:本科生毕业论文的 “救命神器” 全拆解

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/weight?type1https://www.paperxie.cn/weight?type1 一、写在前面&#xff1a;被论文查重和 AIGC 检测逼到崩溃的你&#xff0c;真的不是一个人 凌晨三点的宿舍&#xff0…...

从 99.8% 到 14.9%!Paperxie 降 AIGC:本科生论文通关的「隐形 buff」

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/weight?type1https://www.paperxie.cn/weight?type1 一、写在前面&#xff1a;被 AIGC 检测卡脖子的毕业季&#xff0c;你不是一个人在战斗 当毕业论文从「查重焦虑」升级…...

什么叫低代码?低代码平台能做什么?国内十大低代码平台盘点

在数字化转型浪潮席卷全球的今天&#xff0c;软件开发效率成为企业竞争的关键因素。低代码&#xff08;Low-Code&#xff09;作为一种革命性的开发模式&#xff0c;正以惊人速度改变着传统软件开发的格局&#xff0c;让"人人都是开发者"的愿景逐渐成为现实。本文将深…...

第四篇:GitHub Copilot:IDE里的沉默革命者——最稳代码补全王者,VS Code生态下的生产力核弹

(本篇约7200字,2026年4月最新数据,含高清实操截图与对比图表,作为专栏第四篇长文) 2026年,如果你还在把GitHub Copilot当成“智能Tab键”,那你就错过了它真正的杀伤力。它早已从单纯的代码补全工具,悄然进化成VS Code生态中最稳定、最普适、最具企业级安全保障的生产力…...

Ubuntu 20.04 手动升级 OpenSSL 3.x 的完整指南

1. 为什么需要手动升级OpenSSL&#xff1f; Ubuntu 20.04默认安装的是OpenSSL 1.1.1版本&#xff0c;虽然这个版本仍然在维护周期内&#xff0c;但新发布的OpenSSL 3.x系列带来了许多重要改进。我在实际项目中遇到过这样的情况&#xff1a;某个新开发的加密功能必须依赖OpenSSL…...

OpenClaw技能开发入门:为SecGPT-14B编写自定义漏洞检测模块

OpenClaw技能开发入门&#xff1a;为SecGPT-14B编写自定义漏洞检测模块 1. 为什么需要自定义漏洞检测技能 去年在一次内部红队演练中&#xff0c;我遇到了一个典型问题&#xff1a;现有扫描工具对新型API漏洞的检测覆盖率不足&#xff0c;而手动验证每个可疑端点又极其耗时。…...

Java 21 新特性概览与实战教程

JDK 21 是继 JDK 17 之后的又一个长期支持&#xff08;LTS&#xff09;版本&#xff0c;于 2023 年 9 月发布。它被誉为 Java 历史上最具变革性的版本之一&#xff0c;特别是虚拟线程的引入&#xff0c;彻底改变了 Java 在高并发领域的编程模型。相比 JDK 17&#xff0c;JDK 21…...

从零搭建一套生产可用的K8S日志监控栈:EFK/ELK保姆级配置与避坑指南

从零搭建一套生产可用的K8S日志监控栈&#xff1a;EFK/ELK保姆级配置与避坑指南 在云原生架构中&#xff0c;日志管理就像给系统装上"黑匣子"——当凌晨三点收到告警时&#xff0c;你需要的不是模糊的"系统异常"&#xff0c;而是能精准定位问题的完整上下文…...

OpenClaw邮件处理方案:Qwen2.5-VL-7B自动分类与回复

OpenClaw邮件处理方案&#xff1a;Qwen2.5-VL-7B自动分类与回复 1. 为什么需要邮件自动化助手 每天早晨打开邮箱时&#xff0c;面对堆积如山的未读邮件总让人心生畏惧。作为技术从业者&#xff0c;我的收件箱里混杂着技术订阅、会议邀请、账单通知和各种推广信息&#xff0c;…...

问题1 开播后 观众端第一次进直播间 直播间没有画面 需要 主播重新进直播页面 观众端才有画面问题2 上面的流程走完 观众重新进直播间 直播间看不到画面问题3 不能多观众收看直播啊

需要docker srs webrtc websockdocker cmd 中 启动 srsset CANDIDATElongwen.natapp1.cc && docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8000:8000/udp -p 8000:8000/tcp --env CANDIDATE%CANDIDATE% --env SRS_RTC_TCP_ENABLEDon --env SRS_RTC_TCP_PORT8000 …...

CAN总线终端电阻原理与工程实践详解

1. CAN总线终端电阻的核心作用解析在工业控制和汽车电子领域&#xff0c;CAN总线是最常用的现场总线之一。作为从业十余年的嵌入式工程师&#xff0c;我处理过无数CAN总线异常案例&#xff0c;其中约30%的通信故障都与终端电阻配置不当有关。120Ω这个看似简单的参数&#xff0…...

费马小定理,快速幂

今天显示延续了昨天的背包问题&#xff0c;先是写了一题背包问题&#xff0c;后面就写费马定理加快速幂。费马小定理证明如果一个数p是质数&#xff0c;并且a不是p的倍数&#xff0c;那么一定有a^&#xff08;p-1&#xff09;1&#xff08;mod p);那么自然有a^(p-2)a^-1(mod p)…...

嵌入式Linux网络状态检测方案与优化实践

1. 嵌入式设备网络状态检测实战指南 在嵌入式Linux开发中&#xff0c;网络连接状态的实时监测是个常见但容易被忽视的需求。想象一下&#xff0c;你正在开发一个智能家居网关&#xff0c;突然Wi-Fi断了&#xff0c;但设备还在傻乎乎地发送数据&#xff1b;或者工业现场的设备&a…...

利用Hex view脚本自动化生成符合OEM标准的刷写文件

1. 从手动操作到自动化&#xff1a;为什么需要Hex view脚本 在汽车电子开发领域&#xff0c;每次给ECU刷写新固件都像给汽车做"心脏手术"。我经历过无数次凌晨三点还在手动修改BIN文件的日子——用十六进制编辑器逐个字节检查对齐&#xff0c;手工计算CRC校验值&…...

从硬件视角看RISC-V FENCE:流水线、Cache与指令保序的底层实现

从硬件视角看RISC-V FENCE&#xff1a;流水线、Cache与指令保序的底层实现 在处理器设计中&#xff0c;内存访问的顺序性是一个看似简单却充满挑战的问题。想象一下&#xff0c;当你在厨房同时操作多个灶台时&#xff0c;虽然每个锅里的食材都在按计划烹饪&#xff0c;但火候的…...

【 Postman 使用教程】

一、接口测试介绍 1. 接口分类&#xff1a; 内部接口&#xff1a;系统内部各功能模块之间的接口&#xff08;测试比较详细&#xff09;外部接口&#xff1a;系统与外部系统之间的接口&#xff08;测试基本功能&#xff09; 2. 接口测试的重点&#xff1a; 测试接口数据交换是否…...

知识库别往System Prompt塞了!我用Skill Loading把3000 tokens压缩到100,省下66%成本

上篇我们诊断了System Prompt膨胀病&#xff0c;这篇给解药。 用Skill Loading机制把3000 tokens的垃圾场变成100 tokens的图书馆&#xff0c;60行代码实现知识按需加载&#xff0c;API成本直接砍半。 Skill Loading核心机制 类比&#xff1a;图书馆借书流程 图书馆不会把所有书…...

20轮对话后GPT开始“胡说八道“:我用Subagent分层架构让上下文永不清零

复杂任务跑20轮后&#xff0c;Agent开始"胡说八道"——重复已做过的操作、提出已否决的方案。 这不是模型变笨了&#xff0c;是上下文窗口被污染。本文用Subagent分层架构&#xff0c;让父Agent保持清醒&#xff0c;子Agent承担脏活&#xff0c;实现20轮对话上下文仅…...

如何分析AWR中的Top SQL_通过执行次数与物理读定位低效查询

Top SQL中Executions与Physical Reads需结合分析&#xff1a;执行次数多但物理读低可能暴露应用逻辑缺陷&#xff0c;物理读/执行>1000在OLTP中属异常&#xff0c;需结合执行计划、对象访问、缓存命中率等综合判断根因。怎么看 Top SQL 里的执行次数和物理读是否异常awr 报告…...

c++如何读取BMP位图文件并精确提取每个像素点的RGB值【实战】

直接用fread读BMP会错乱因像素数据BGR存储、行末补零对齐且从左下到右上排列&#xff1b;需跳过bfOffBits&#xff0c;按每行字节数对齐读取并反向索引&#xff0c;再手动转为RGB。为什么直接用 fread 读 BMP 文件会得到错乱的 RGB 顺序&#xff1f;BMP 文件头和信息头之后&…...

2026.4.5总结

今天是清明节&#xff0c;祭祖的日子。晚上跟妹妹和姐姐捞了不少家常。聊的是关于上一年自己做过的一些愚蠢事。读书的时候没接触过社会&#xff0c;导致在毕业时&#xff0c;吃了不少亏&#xff0c;也被坑了不少钱。我妹称这叫见世面。确实&#xff0c;刚毕业时&#xff0c;感…...

Python集合怎么去重_Set数据结构特性与交并差集合运算

set()去重不生效因只支持不可变类型&#xff0c;含列表、字典等会报TypeError&#xff1b;需转为可哈希形式如tuple(sorted(d.items()))&#xff1b;自定义类须实现__hash__和__eq__&#xff1b;set无序&#xff0c;保序用dict.fromkeys()&#xff1b;符号运算要求两边为set&am…...

CSS如何实现文字加粗而不改变宽度_利用text-shadow模拟加粗

会&#xff0c;text-shadow模拟加粗因软边阴影导致文字模糊&#xff0c;尤其小字号或Retina屏&#xff1b;需设blur-radius为0&#xff0c;用多方向1px硬边阴影&#xff08;如-1px 0 0, 1px 0 0等&#xff09;并启用GPU加速。text-shadow模拟加粗会导致文字模糊&#xff1f;会&…...

硬件发烧友玩法:多GPU分配OpenClaw调用Qwen3-32B

硬件发烧友玩法&#xff1a;多GPU分配OpenClaw调用Qwen3-32B 1. 为什么需要多GPU分配 作为一个长期折腾AI本地部署的硬件爱好者&#xff0c;我最近在尝试用OpenClaw对接Qwen3-32B模型时遇到了显存瓶颈。单卡RTX4090D的24GB显存在处理复杂任务时经常捉襟见肘&#xff0c;特别是…...

揭秘openGauss向量化执行引擎代价模型

揭秘openGauss向量化执行引擎代价模型openGauss的向量化执行引擎针对列存&#xff0c;生成执行计划后根据配置项是否开启直接决定是否将执行计划转换成向量化执行计划来执行。若向量化执行引擎在行存上执行就需要将数据转换成VectorBatch即列存的形式才可执行&#xff0c;这个转…...