Arthas查看Spring配置


在開發過程經常有同學問:“我這個配置更新提交了,怎么樣知道項目中是否已經更新使用新值?” 常用的方法是添加日志打印該值判斷是否更新。今天我們用Arthas來實現項目中配置值實時讀取。

Arthas 簡介

Arthas 是Alibaba開源的Java診斷工具。使用 Arthas 可以很方便幫助我們排查線上問題。下面簡單介紹幾個常用的命令以及使用的場景。

  • jad 命令反編譯指定已加載類的源碼。在代碼修改了不生效,懷疑代碼沒有部署時可以通過該命令查看源碼。
  • thread 命令查看當前線程信息,線程的堆棧。線程池線程爆滿時用該命令查看阻塞線程;CPU使用率過高用該命令查看占用CPU最高的線程。
  • jvm 命令查看當前JVM信息。查看使用什么垃圾回收算法、線程數和阻塞線程數等。
  • watch 命令方法執行數據觀測。觀察方法入參和返回值,或者報錯信息等。
  • trace 命令方法內部調用路徑,並輸出方法路徑上的每個節點上耗時。查看方法內部調用所有的接口和每個接口對應的耗時,這個可以很好的掌控接口性能質量。
  • tt 命令記錄下指定方法每次調用的入參和返回信息,並能對這些不同的時間下調用進行觀測。需要重現某個問題時,需要前端同學配合點擊,用這個命令可以代替前端同學,回放之前的請求。
  • getstatic 命令可以查看類的靜態屬性。
  • ognl 命令可以查看類的靜態屬性,並且可以做很多不可以描述的事情!

上面的命令是作為開發經常使用到的,具體怎么樣使用Arthas請看官網。

OGNL竊取SpringContext屬性

假設大家都知道 SpringBoot 讀取配置之后存在 ConfigurableApplicationContext 的 environment 中。如果有不知道的,可以在 PropertySourceBootstrapConfiguration#initialize 方法里打個斷點debug調試一波😏。下面用一個例子操作一波。

步驟一

application.properties文件中添加 author=Greiz 鍵值對。

步驟二

想辦法拿到項目中 ApplicationContext 對象。ognl只獲取靜態屬性,所以我們一般需要查找項目中是否存在靜態的ApplicationContext對象。這里面我就自己創建了一個類來提供靜態的ApplicationContext。

package com.greiz.demo.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ConfigHandler implements InitializingBean, ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(applicationContext.getEnvironment().getProperty("author"));
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ConfigHandler.applicationContext = applicationContext;
    }
}

這種方式是不是到處可見。如果用Dubbo的,Dubbo框架里com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory 持有靜態的 ApplicationContext 對象。

步驟三

使用ognl獲取靜態 ApplicationContext 屬性。

ognl '#context=@com.greiz.demo.config.ConfigHandler@applicationContext,#context.getEnvironment().getProperty("author")'

逗號之前是獲取 ApplicationContext 對象並賦值給 context。逗號后面的獲取 Environment 對象中的屬性。這個 "author" 屬性就是application.properties 配置的,也可以是遠程的配置文件。

對應的結果

其實只要獲取到ApplicationContext 對象,我們就可以對Spring容器為所欲為了,比如下面不知恥辱的行為:

@Component
public class Greiz {

    @Value("${userName}")
    private String name;
    @Value("${userAge}")
    private Integer age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

可以獲取Spring容器的所有bean,然后調用對應的方法。

總結

熟悉Arthas 工具常用命令;了解配置最終所保存的對象;提供靜態屬性的 ApplicationContext 對象;ognl獲取Spring容器鑰匙ApplicationContext,然后做你們想做的事。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM