You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从application.properties读取变量返回null问题求助

问题分析与解决方案

你遇到的所有空指针问题根源一致:TokenUtils未被Spring容器管理,且Spring不支持直接给静态字段注入依赖/配置属性,以下是具体问题拆解和修正方案:


各方案的核心问题

方案一

  1. TokenUtils未添加@Component等Spring Bean注解,Spring不会处理其中的@Autowired注入
  2. Spring不支持给静态字段注入依赖,private static ConfigProperties configProp始终为null
  3. ConfigProperties的字段命名错误:前缀custom.data.jwt已包含jwt,字段jwt_secret会匹配custom.data.jwt.jwt-secret而非目标配置custom.data.jwt.secret

方案二

  1. 同方案一,TokenUtils非Spring Bean,静态字段configProp无法被注入
  2. 静态变量初始化时机早于Spring注入流程,调用configProp.getConfigValue()时依赖还未初始化

方案三

  1. TokenUtils非Spring Bean,@Value注解不会被Spring解析
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:20:40