公司动态
Spring MVC 项目中使用 @Value 注解读取 Properties 配置的完整指南
问题背景最近在 Spring MVC 项目中集成邮件发送功能时遇到了通过Value注解从*.properties文件读取配置值的问题。在单元测试junit中可以正常获取但在业务代码中却获取到null。解决方案使用 Value 注解读取配置Spring 除了传统的 XML 配置方式外还可以通过Value注解来获取*.properties文件中的配置值。1. 配置实体类Value注解需要 Spring 的注解扫描支持因此需要在 Spring 配置中扫描实体类所在的包并在实体类上添加Component注解。Component public class MailBean { // 实体类添加 Component让 Spring 扫描并管理默认单例模式 // 功能从 data.properties 资源文件中读取邮件配置 Value(#{configProperties[emailhost]}) private String emailHost; Value(#{configProperties[emailform]}) private String emailFrom; Value(#{configProperties[emailname]}) private String emailUsername; Value(#{configProperties[emailpassword]}) private String emailPassword; // Getter 方法 public String getEmailHost() { return emailHost; } public String getEmailFrom() { return emailFrom; } public String getEmailUsername() { return emailUsername; } public String getEmailPassword() { return emailPassword; } }2. Spring 配置文件在applicationContext.xml中配置组件扫描和属性文件加载!-- 自动扫描 com.myweb 包将带有注解的类纳入 Spring 容器管理 -- context:component-scan base-packagecom.myweb/context:component-scan !-- 引入配置文件 -- bean idconfigProperties classorg.springframework.beans.factory.config.PropertiesFactoryBean property namelocations list valueclasspath:data.properties/value valueclasspath:application.properties/value /list /property /bean bean idpropertyConfigurer classorg.springframework.beans.factory.config.PreferencesPlaceholderConfigurer property nameproperties refconfigProperties / /bean3. 属性文件配置data.properties文件内容emailhost邮箱的网关 emailname你的用户名 emailpassword你的密码 emailform发件邮箱 // 具体值需根据自身情况配置问题现象与排查单元测试正常通过 JUnit 测试可以正常获取配置值Test public void test() { ApplicationContext appContext new ClassPathXmlApplicationContext(applicationContext.xml); MailBean connInfo appContext.getBean(MailBean.class); System.out.println(connInfo.getEmailHost()); System.out.println(connInfo.getEmailFrom()); System.out.println(connInfo.getEmailUsername()); // 可以正常获取 }业务代码中获取 null但在具体业务代码中使用时获取到的却是null。问题原因与解决方案问题原因在业务代码中仍然使用new MailBean()来创建对象。但MailBean已经通过Component注解加入了 Spring 容器的管理并且默认是单例模式。直接new创建的对象不会被 Spring 管理因此Value注解不会生效。正确做法在业务类中通过依赖注入的方式获取MailBean实例Resource private MailBean mailBean;同时业务类本身也需要交给 Spring 管理添加相应的注解如Controller、Service、Repository或Component。在 JUnit 测试中通过appContext.getBean(MailBean.class)获取的是 Spring 容器管理的 Bean所以能正常取值。在业务代码中必须通过Resource或Autowired注入否则无法获取到正确的 Bean。常见警告及处理在 Spring 配置文件中添加上述配置时可能会遇到以下警告警告Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKey ...该警告是由于写入注册表时权限不足引起的。解决方法打开命令窗口输入regedit打开注册表管理器导航到HKEY_LOCAL_MACHINE\Software\JavaSoft\在JavaSoft下创建Prefs项即可总结通过Value注解读取*.properties配置时需要注意实体类需要添加Component等 Spring 管理注解Spring 配置中需要扫描实体类所在的包在业务代码中必须通过依赖注入获取 Bean不能直接new创建遇到注册表权限警告时手动创建相应的注册表项即可解决