从application.properties读取变量返回null问题求助
问题分析与解决方案
你遇到的所有空指针问题根源一致:TokenUtils未被Spring容器管理,且Spring不支持直接给静态字段注入依赖/配置属性,以下是具体问题拆解和修正方案:
各方案的核心问题
方案一
TokenUtils未添加@Component等Spring Bean注解,Spring不会处理其中的@Autowired注入- Spring不支持给静态字段注入依赖,
private static ConfigProperties configProp始终为null ConfigProperties的字段命名错误:前缀custom.data.jwt已包含jwt,字段jwt_secret会匹配custom.data.jwt.jwt-secret而非目标配置custom.data.jwt.secret
方案二
- 同方案一,
TokenUtils非Spring Bean,静态字段configProp无法被注入 - 静态变量初始化时机早于Spring注入流程,调用
configProp.getConfigValue()时依赖还未初始化
方案三
TokenUtils非Spring Bean,@Value注解不会被Spring解析- Spring不支持给静态字段直接注入配置属性
正确实现方案
步骤1:配置属性类(规范写法)
创建Spring管理的配置类,正确映射application.properties中的字段:
package com.XX.ZZ.security; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "custom.data.jwt") public class JwtProperties { // 字段名与配置项后缀对应:secret → custom.data.jwt.secret private String secret; // expiration → custom.data.jwt.expiration private long expiration; // Getter & Setter public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } public long getExpiration() { return expiration; } public void setExpiration(long expiration) { this.expiration = expiration; } }
步骤2:修正TokenUtils(推荐非静态写法)
将TokenUtils转为Spring Bean,使用构造注入依赖(符合Spring最佳实践):
package com.XX.ZZ.security; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.stereotype.Component; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class TokenUtils { private final String jwtSecret; private final long jwtExpiration; // 构造注入Spring管理的JwtProperties实例 public TokenUtils(JwtProperties jwtProperties) { this.jwtSecret = jwtProperties.getSecret(); this.jwtExpiration = jwtProperties.getExpiration(); } public String createToken(String name, String email){ long expirationTime = jwtExpiration * 1000; Date expirationDate = new Date(System.currentTimeMillis() + expirationTime); Map<String, Object> extra = new HashMap<>(); extra.put("name", name); return Jwts.builder() .setSubject(email) .setExpiration(expirationDate) .addClaims(extra) .signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes())) .compact(); } public UsernamePasswordAuthenticationToken getAuthentication(String token){ try { Claims claims = Jwts.parserBuilder() .setSigningKey(jwtSecret.getBytes()) .build() .parseClaimsJws(token) .getBody(); String email = claims.getSubject(); return new UsernamePasswordAuthenticationToken(email,null, Collections.emptyList()); } catch (JwtException e){ return null; } } }
若需保留静态方法(不推荐,不利于测试)
如果必须使用静态方法,可通过@PostConstruct初始化静态字段:
@Component public class TokenUtils { private static String jwtSecret; private static long jwtExpiration; private final JwtProperties jwtProperties; public TokenUtils(JwtProperties jwtProperties) { this.jwtProperties = jwtProperties; } // Spring Bean初始化完成后赋值静态字段 @PostConstruct public void initStaticProps() { jwtSecret = jwtProperties.getSecret(); jwtExpiration = jwtProperties.getExpiration(); } // 静态方法保持不变 public static String createToken(String name, String email){ // 原有代码逻辑 } public static UsernamePasswordAuthenticationToken getAuthentication(String token){ // 原有代码逻辑 } }
内容的提问来源于stack exchange,提问作者LautaroColella
相关产品推荐
相关产品推荐

