Arthas的一個很重要的應用場景,就是查看運行時的數據,但有時須要動態的查看數據,或者數據過多,須要動態篩選,比較複雜的規則就須要靠OGNL了。java
下面介紹一些經常使用的arthas中ognl的操做,測試代碼以下,springboot工程:spring
@RequestMapping("send") public String send(HttpServletRequest request, HttpServletResponse response){ return doSend(createUserList(),false); } public String doSend(List<User> userList,boolean flag){ System.out.println("doSend"); return "success"; } private List<User> createUserList(){ List<User> userList = new ArrayList<>(); for (long i = 0; i < 10; i++) { User user = new User(); user.setId(i); user.setUsername("u"+i); userList.add(user); } return userList; } class User { private String username; private Long id; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } private String convert(){ return id+"_"+username; } }
watch com.example.httpclientdemo.HttpclientDemoApplication send 'params[0]' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 45 ms. ts=2019-09-26 15:13:38; [cost=0.267515ms] result=@RequestFacade[ request=@Request[org.apache.catalina.connector.Request@5b518aa4], sm=@StringManager[org.apache.tomcat.util.res.StringManager@6ffbca2e], ]
watch com.example.httpclientdemo.HttpclientDemoApplication send 'params[0].class.name' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 50 ms. ts=2019-09-26 15:15:17; [cost=0.252717ms] result=@String[org.apache.catalina.connector.RequestFacade]
watch com.example.httpclientdemo.HttpclientDemoApplication send 'params[0].getMethod()' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 55 ms. ts=2019-09-26 15:15:49; [cost=0.289059ms] result=@String[GET]
簡單的說,就是查看集合中元素的屬性或者方法返回值,和lambda裏的map很像apache
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.username}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 28 ms. ts=2019-09-26 15:19:49; [cost=0.006187ms] result=@ArrayList[ @String[u0], @String[u1], @String[u2], @String[u3], @String[u4], @String[u5], @String[u6], @String[u7], @String[u8], @String[u9], ]
還能夠在投影中調用方法tomcat
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.convert()}' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 83 ms. ts=2019-09-26 15:30:04; [cost=0.349277ms] result=@ArrayList[ @String[0_u0], @String[1_u1], @String[2_u2], @String[3_u3], @String[4_u4], @String[5_u5], @String[6_u6], @String[7_u7], @String[8_u8], @String[9_u9], ]
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{? #this.id > 8}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 33 ms. ts=2019-09-26 15:23:10; [cost=0.006812ms] result=@ArrayList[ @User[ username=@String[u9], id=@Long[9], ], ]
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{? #this.username.endsWith("9")}.size()' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 27 ms. ts=2019-09-26 15:33:12; [cost=0.165327ms] result=@Integer[1]
這裏須要分清楚,在條件表達式裏寫過濾條件和直接在觀察表達式裏寫過濾條件的區別:springboot
固然也能夠在條件表達式裏寫Ongl,效果是相似的:app
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.username}' 'params[0].{? #this.id>7}.size()>0' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 39 ms. ts=2019-09-26 15:45:12; [cost=0.19965ms] result=@ArrayList[ @String[u0], @String[u1], @String[u2], @String[u3], @String[u4], @String[u5], @String[u6], @String[u7], @String[u8], @String[u9], ]
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].size().(#this>5? 20+#this:10+#this)' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 52 ms. ts=2019-09-26 15:58:36; [cost=0.179407ms] result=@Integer[30]
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{^#this.username.startsWith("u")}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 141 ms. ts=2019-09-26 17:18:01; [cost=0.41405ms] result=@ArrayList[ @User[ username=@String[u0], id=@Long[0], this$0=@HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36[com.example.httpclientdemo.HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36@d5d5b7f], ], ]
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{$#this.username.startsWith("u")}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 84 ms. ts=2019-09-26 17:18:32; [cost=0.036367ms] result=@ArrayList[ @User[ username=@String[u9], id=@Long[9], this$0=@HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36[com.example.httpclientdemo.HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36@d5d5b7f], ], ]
watch 時調用靜態方法 watch com.example.httpclientdemo.HttpclientDemoApplication doSend '@java.lang.Thread@currentThread()' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 31 ms. ts=2019-09-26 17:20:29; [cost=0.13471ms] result=@TaskThread[ log=@DirectJDKLog[org.apache.juli.logging.DirectJDKLog@2f1ab57a], creationTime=@Long[1569484802267], ]
ognl 調用靜態方法
注意:ognl會受classloader的限制,若是在tomcat之類的環境下,會找不到對應的類測試
ognl '@com.example.httpclientdemo.SpringApplicationContextHolder@getBean("your bean name")'
ognl獲取靜態屬性this
ognl '@com.example.httpclientdemo.SpringApplicationContextHolder@isDestroyed'
getstat獲取靜態屬性code
getstatic com.example.httpclientdemo.SpringApplicationContextHolder applicationContext