最近在优化项目,发现项目中使用的hikaridatasource连接池,原先的SQL打印使用的是自定义的拦截器,打印的还有问题,所以打算使用p6spy来记录SQL,使用时想针对慢SQL进行钉钉提醒,所以自定义了p6spy记录消息,代码如下:
@Component
public class P6SpyLogger implements MessageFormattingStrategy {
@Value("${spring.profiles.active}")
private String profile;
@Override
public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
String content = !"".equals(sql.trim()) ? "[ " + LocalDateTime.now() + " ] --- | SQL耗时 "
+ elapsed + "ms | 连接信息: " + category + connectionId + "\n "
+ sql + ";" : "";
if (elapsed >= 2000) {
DingDingMsgSendUtils.sendDingDingGroupMsg("【重要消息】" + profile + "环境,发现慢SQL,请检查:" + content);
}
if (!profile.equals("dev")) {
return "";
}
return content;
}
}
然而获取到的profile一直未null,获取不到,网上查找了好多,发现
@Value,两者必须使用在bean的实例中,例如被@Controller,@Service,@Component等注解的类里边。
咦。。。那我没问题啊,是用被@Component注解的类啊,百思不得其解,翻阅多篇博客,终于找到了原因。原来,使用@Value的类,在spring中,不能直接通过new 操作符来使用,而是应该通过spring的注解 @Autowired 来使用(这个操作相信大家都会,就不演示了)。然后我看了p6spy的源代码,发现确实是通过new操作来使用的P6SpyLogger。这时我们应该怎么获取呢?
第一种方法
@Component
@Data
public class BootstrapInfo {
@Value("${spring.profiles.active}")
private String active;
private static String profile;
@PostConstruct
public void setProfile() {
profile = this.active;
}
public static String getProfile() {
return profile;
}
}
首选要在BootstrapInfo里建一个static的变量,然后使用@Value获取yml配置文件的值。最后关键就是使用 @PostConstruct 熟悉将yml中配置的值赋给本地的变量,这样后面的静态方法就能使用了。
注意事项:
注意BootstrapInfo类使用了 @Component 属性注解了说明是需要在启动类 Application 启动的时候加载的,所以我们本地写一个方法调用 BootstrapInfo 的时候是获取不到 profile的。
第二种方法
通过YamlPropertiesFactoryBean这种方式去获取yml中的值
代码如下:
public static Object getBootstrapYml(Object key){
Resource resource = new ClassPathResource("bootstrap.yml");
Properties properties = null;
try {
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(resource);
properties = yamlFactory.getObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return properties.get(key);
}
public static void main(String[] args) {
System.out.println(getBootstrapYml("spring.profiles.active"));
}
注意:
yml和properties配置文件的获取方式可能会有所不同,要注意