2022-06-07:注入配置
在开发应用程序时,经常要读取配置文件。最常用的配置方法是以Key=Value的形式写在.properties文件中。
例如,MailService根据配置的app.zone=Asia/Shanghai来决定使用哪个时区。要读取配置文件,我们可以使用上一节讲到的Resource来读取位于classpath下的一个app.properties文件。但是这样仍然比较繁琐。
Spring容器还提供了一个更简单的@PropertySource来自动读取配置文件。我们只需要在@Configuration配置类上再添加一个注解:
@Configuration @ComponentScan @PropertySource("app.properties") // 表示读取classpath的app.properties public class AppConfig { @Value("${app.zone:Z}") String zoneId; @Bean ZoneId createZoneId() { return ZoneId.of(zoneId); } }
Spring容器看到@PropertySource("app.properties")注解后,自动读取这个配置文件,然后,我们使用@Value正常注入:
@Value("${app.zone:Z}")
String zoneId;
注意注入的字符串语法,它的格式如下:
- "${app.zone}":读取Key为app.zone的Value,如果Key不存在,启动将报错;
- "${app.zone:Z}":读取Key为app.zone的Value,如果Key不存在,就是用默认值Z。
这样一来,我们就可以根据app.zone的配置来创建ZoneId。
还可以把注入的注解写到方法参数中:
@Bean ZoneId createZoneId(@Value("${app.zone:Z}") String zoneId) { return ZoneId.of(zoneId); }
可见,先使用@PropertySource读取配置文件,然后通过@Value以${key:defaultValue}的形式注入,可以极大地简化读取配置的麻烦。
另一种注入配置的方式是先通过一个简单的JavaBean持有所有的配置,例如,一个SmtpConfig:
@Component public class SmtpConfig { @Value("${smtp.host}") private String host; @Value("${smtp.port:25}") private int port; public String getHost() { return host; } public int getPort() { return port; } }
然后在需要读取的地方,使用#{smtpConfig.host}注入:
@Component public class MailService { @Value("#{smtpConfig.host}") private String smtpHost; @Value("#{smtpConfig.port}") private int smtpPort; }
注意观察#{}这种注入语法,它和${key}不同的是,#{}表示从JavaBean读取属性。"#{smtpConfig.host}"的意思是,从名称为smtpConfig的Bean读取host属性,即调用getHost()方法。一个Class名为SmtpConfig的Bean,它在Spring容器中的默认名称就是smtpConfig,除非用@Qualifier指定了名称。
使用一个独立的JavaBean持有所有属性,然后在其他Bean中以#{bean.property}注入的好处是:多个Bean都可以引用同一个Bean的某个属性。例如,如果SmtpConfig决定从数据库中读取相关配置项,那么MailService注入的@Value("#{smtpConfig.host}")仍然可以不修改正常运行。
小结
- Spring容器可以通过@PropertySource自动读取配置,并以@Value("${key}")的形式注入;
- 可以通过${key:defaultValue}指定默认值;
- 以#{bean.property}形式注入时,Spring容器自动把指定Bean的指定属性值注入。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2021-06-07 QT:中文字符串与“常量中有字符串”报错
2020-06-07 Pycharm:设置自带控制台的python版本