原本这个常量是写在类文件里的,但后来发现 appId和appSecret 要变更,想着还是写到配置文件中吧!
public class Constant {
/**
* 合作方申请的appId
* */
public static final String APP_ID = "123456789";
/**
* 合作方申请的appSecret
*/
public static final String APP_SECRET = "asdghlgjfhgkhjghfhjgfghjfgh";
}
调用处代码:
public static void method() {
String appId = Constant.APP_ID;
String appSecret = Constant.APP_SECRET;
}
于是,使用 @Component和@Value 注入两个参数。并添加get方法
@Component
public class Constant {
/**
* 合作方申请的appId
* */
@Value("${cn.appId}")
public String appId;
/**
* 合作方申请的appSecret
*/
@Value("${cn.appSecret}")
public String appSecret;
public String getAppId() {
return appId;
}
public String getSecret() {
return appSecret;
}
}
yml中:
cn:
appId: 121232424
appSecret: dfssssgsdfhdfdfjjjjjjjjjjjjjjj
因为不是静态的了,只能先 new一下,再通过getter()调用。
public static void method() {
Constant constant = new Constant();
String appId = constant.getAppId();
String appSecret = constant.getSecret();
}
但是,运行后发现报错,值为null
于是排查,排查,排查…… 最后发现是不能用 new ,那怎么办呢?
通过不断的与“通义灵码”沟通,他最终给了一个解决方案:
静态方法中如何使用yml文件配置的字段?
灵码:在静态方法中使用YAML文件配置的字段,需要将这些字段加载为静态变量。以下是详细的步骤和修复代码:
1. 简要解释报错原因
报错原因是constant是实例变量(非静态字段),而method方法是静态方法。在静态方法中无法直接访问实例变量,因为静态方法属于类本身,而非某个具体对象。
2. 提供修复建议
将constant改为静态变量:通过Spring的@Value注解或@ConfigurationProperties注解将YAML文件中的配置加载到静态变量中。
使用@PostConstruct初始化静态变量:确保在Spring容器初始化后,静态变量能够正确加载配置。
@Component
public class Constant {
/**
* 合作方申请的appId
* */
@Value("${cn.appId}")
public String appId;
/**
* 合作方申请的appSecret
*/
@Value("${cn.appSecret}")
public String appSecret;
public static String APP_ID;
public static String APP_SECRET;
@PostConstruct
public void init() {
APP_ID = this.appId;
APP_SECRET = this.appSecret;
}
}
调用处也改回原来的
public static void method() {
String appId = Constant.APP_ID;
String appSecret = Constant.APP_SECRET;
}
再次运行,OK!虽然不是很懂,但大致意思是懂得。
于是又问 “为什么在类加载时会执行这段代码”
代码解释
这段代码使用了@PostConstruct注解,该注解是Java EE规范中的一部分(也支持Spring框架)。当一个类被标注为Spring容器中的组件(如通过@Component注解),并且该类的实例被创建后,Spring会在依赖注入完成后自动调用标记了@PostConstruct的方法。因此,在类加载并初始化完成后,init()方法会被执行,用于将appId和appSecret的值赋给静态变量APP_ID和APP_SECRET。
原理解析
类加载与实例化:Spring容器在启动时会扫描带有@Component注解的类,并将其实例化。
依赖注入:通过@Value注解,Spring会将配置文件中的cn.appId和cn.appSecret值注入到appId和appSecret字段中。
生命周期回调:@PostConstruct标记的方法会在依赖注入完成后立即执行,确保在Bean完全初始化后进行额外的设置操作
这下算是基本懂了!
每天进步一点点就很OK啦!