SpringBoot使用注解对静态变量赋值方式

 更新时间:2026年06月08日 10:48:33   作者:编程侠Java  
SpringBoot框架中使用@Value注解赋值给静态变量时遇到的问题及解决方案,详细解释原因并提供正确实现方法,包括使用set方法赋值及注意事项

SpringBoot框架,使用一些注解,能够快速进行开发,比如在配置文件application.yml中设置自定义参数,然后在业务开发时开发时使用注解@Value,就可以获取到配置文件中的参数值。

但是对于某些业务,传递的参数必须是静态变量,这时候我们发现,直接在参数上添加注解@Value,根本获取不到值,返回的值为null。这是为什么呢?该如何使用注释对静态变量赋值呢?

原因

springboot不支持把值赋值给静态变量,因为静态变量不属于对象,只属于类,也就是说在类被加载字节码的时候变量已经初始化了,也就是给该变量分配内存了,导致spring忽略静态变量。

所以这种写法就是错误的,这样是无法注入的,在使用该变量的时候会导致空指针错误:

解决方案

使用@Value 在set 方法去赋值 ,并且 set方法不能声明为statis。注意set方法的参数可以任意命名,但不能跟属性名相同。

举例说明

我在项目中配置了redis哨兵集群,需要使用application.yml中的配置,并且使用的变量需是静态变量。

application.yml中的redis模块的配置如下:

  redis:
    password: root
    timeout: 5000
    jedis:
      pool:
        # 最大连接数
        max-active: 100
        # 最大阻塞等待时间ms(负数表示没有限制)
        max-wait: 10000
        # 最大空闲连接
        max-idle: 20
        # 最小空闲连接
        min-idle: 8
    sentinel:
      master: mymaster
      # 哨兵的IP:Port列表
      nodes:127.0.0.1:26379;127.0.0.1:26380;127.0.0.1:26381

Redis静态变量赋值的类如下(小细节:set方法参数名与属性名设置不同):

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author 编程侠
 * @projectName springboot
 * Redis 静态变量配置类
 */
@Component
public class RedisConnectConfig {

    public static String MAX_ACTIVE;
    public static String MAX_IDLE;
    public static String MAX_WAIT;
    public static String MASTER;
    public static String NODES;
    public static String TIMEOUT;
    public static String PASSWORD;

    //使用@Value 注入静态参数  只能在set 方法去赋值 , set方法不能是statis
    @Value("${spring.redis.jedis.pool.max-active}")
    private void setMaxActive(String maxActive){
        MAX_ACTIVE = maxActive;
    }

    @Value("${spring.redis.jedis.pool.max-idle}")
    private void setMaxIdle(String maxIdle){
        MAX_IDLE = maxIdle;
    }

    @Value("${spring.redis.jedis.pool.max-wait}")
    private void setMaxWait(String maxWait){
        MAX_WAIT = maxWait;
    }

    @Value("${spring.redis.sentinel.master}")
    private void setMaster(String master){
        MASTER = master;
    }

    @Value("${spring.redis.sentinel.nodes}")
    private void setNODES(String nodes){
        NODES = nodes;
    }

    @Value("${spring.redis.timeout}")
    private void setTIMEOUT(String timeout){
        TIMEOUT = timeout;
    }

    @Value("${spring.redis.password}")
    private void setPASSWORD(String password){
        PASSWORD = password;
    }
}

使用redis的静态变量类如下:

static {
	try {
		if (shardedJedisSentinelPool == null) {
			GenericObjectPoolConfig config = new GenericObjectPoolConfig();
			int max_total = Integer.parseInt(RedisConnectConfig.MAX_ACTIVE);
			config.setMaxTotal(max_total);
			int max_idle = Integer.parseInt(RedisConnectConfig.MAX_IDLE);
			config.setMaxIdle(max_idle);
			int max_wait = Integer.parseInt(RedisConnectConfig.MAX_WAIT);
			config.setMaxWaitMillis(max_wait);

			List<String> masters = new ArrayList<String>();
			Set<String> sentinels = new HashSet<String>();
			String masterName = RedisConnectConfig.MASTER;
			String hostAndPort = RedisConnectConfig.NODES;

			for (String strMaster : masterName.split(";")) {
				masters.add(strMaster.trim());
			}

			for (String strHostAndPort : hostAndPort.split(";")) {
				sentinels.add(strHostAndPort.trim());
			}
			int timeout =  Integer.parseInt(RedisConnectConfig.TIMEOUT);
			String password = RedisConnectConfig.PASSWORD;
			shardedJedisSentinelPool = new ShardedJedisSentinelPool(masters, sentinels, config, timeout,password);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

我们也可以在同一个类中既声明普通变量,又声明静态变量:

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
 * 支付宝扫码支付
 */
@Configuration
@Data
public class AlipayScanConfig {

    /**************普通变量,使用@Value()作用在参数上即可*******************/

    @Value("${alipay.scan.timeoutExpress}")
    private String timeoutExpress;

    @Value("${alipay.scan.charset}")
    private String charset;

    @Value("${alipay.scan.format}")
    private String format;

    @Value("${alipay.scan.notifyUrl}")
    private String notifyUrl;

    @Value("${alipay.scan.downloadPath}")
    private String downloadPath;


    /**************静态变量,使用@Value 注入静态参数  只能在set方法去赋值 , set方法不能是statis*******************/

    public static String ZFBINFO_PROPERTIES;

    @Value("${alipay.scan.zfbinfoProperties}")
    private void setZfbinfoProperties(String zfbinfoProperties){
        ZFBINFO_PROPERTIES = zfbinfoProperties;
    }
}

在使用时有点不太一样

普通变量:

@Autowired
private AlipayWithholdConfig alipayWithholdConfig;


alipayWithholdConfig.getNotifyUrl();//通过get方法取值

静态变量,直接在类上取变量:

@Autowired
private AlipayWithholdConfig alipayWithholdConfig;
AlipayWithholdConfig.appId;//直接取属性

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java面试synchronized偏向锁后hashcode存址

    Java面试synchronized偏向锁后hashcode存址

    这篇文章主要为大家介绍了Java面试中synchronized偏向锁后hashcode存址详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Mybatis-Plus实现用户ID自增出现的问题解决

    Mybatis-Plus实现用户ID自增出现的问题解决

    项目基于 SpringBoot + MybatisPlus 3.5.2 使用数据库自增ID时, 出现重复键的问题,本文就来介绍一下解决方法,感兴趣的可以了解一下
    2023-09-09
  • JAVA IO API使用详解

    JAVA IO API使用详解

    本文通过理论、用法、实例详细说明了JAVA IO的使用,大家参考其中的实例代码实现自己的JAVA IO程序
    2013-11-11
  • Java的基本数据类型和运算方法(必看篇)

    Java的基本数据类型和运算方法(必看篇)

    下面小编就为大家带来一篇Java的基本数据类型和运算方法(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 详谈Java几种线程池类型介绍及使用方法

    详谈Java几种线程池类型介绍及使用方法

    下面小编就为大家带来一篇详谈Java几种线程池类型介绍及使用方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Spring为什么不推荐使用@Autowired注解详析

    Spring为什么不推荐使用@Autowired注解详析

    @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下
    2021-11-11
  • Spring websocket并发发送消息异常的解决

    Spring websocket并发发送消息异常的解决

    本文主要介绍了 Spring websocket并发发送消息异常的解决,当多个线程同时尝试通过 WebSocket 会话发送消息时,会抛出异常,下面就来解决一下,感兴趣的可以了解一下
    2023-09-09
  • Java实现WGS84/百度/腾讯/高德等主流的地理坐标转换

    Java实现WGS84/百度/腾讯/高德等主流的地理坐标转换

    这篇文章主要为大家详细介绍了如何使用Java实现WGS84,百度,腾讯,高德等主流的地理坐标转换,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2025-12-12
  • JAVA多线程CountDownLatch使用详解

    JAVA多线程CountDownLatch使用详解

    这篇文章主要为大家详细介绍了JAVA多线程CountDownLatch的使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 一篇文章彻底搞懂面试中常被问的各种“锁”

    一篇文章彻底搞懂面试中常被问的各种“锁”

    这篇文章主要给大家介绍了关于面试中常被问的各种“锁”的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05

最新评论