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

java注解参数怎么加变量 java注解中使用变量_java注解参数怎么加变量


但是对于某些业务,传递的参数必须是静态变量,这时候我们发现,直接在参数上添加注解@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;//直接取属性