1. 在跟蹤源代碼的時候,要追著源代碼打斷點,不然不知道每一步執(zhí)行到那里。 有時候有的方法被多個地方調用,這時無法確認走哪個方法,改怎么辦呢? 可以提前通過打調用棧的方式把整個流程弄通,然后在關鍵點打斷點,這樣效率更高。 2.打印方法的調用鏈(堆棧)兩種方式: 正常方式 @Override public SimWeight computeWeight(float boost, CollectionStatistics collectionStats, TermStatistics... termStats) { /* Exception e=new Exception(); e.printStackTrace();*/ java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces(); StackTraceElement[] ste = ts.get(Thread.currentThread()); for (StackTraceElement s : ste) { System.out.println('###################################'+s.getClassName()+'$'+s.getMethodName()); } //業(yè)務邏輯 return new DavidStats(field,K_length,KE_length, termStats) ; } 打印結果 ###################################java.lang.Thread$dumpThreads###################################java.lang.Thread$getAllStackTraces###################################org.apache.lucene.search.similarities.DavidSimilarity$computeWeight###################################org.apache.lucene.search.SynonymQuery$SynonymWeight$<init>###################################org.apache.lucene.search.SynonymQuery$createWeight###################################org.apache.lucene.search.IndexSearcher$createWeight###################################org.apache.lucene.search.IndexSearcher$createNormalizedWeight###################################org.apache.lucene.search.IndexSearcher$search###################################org.apache.solr.search.SolrIndexSearcher$buildAndRunCollectorChain###################################org.apache.solr.search.SolrIndexSearcher$getDocListNC###################################org.apache.solr.search.SolrIndexSearcher$getDocListC###################################org.apache.solr.search.SolrIndexSearcher$search###################################org.apache.solr.handler.component.QueryComponent$doProcessUngroupedSearch###################################org.apache.solr.handler.component.QueryComponent$process###################################org.apache.solr.handler.component.SearchHandler$handleRequestBody###################################org.apache.solr.handler.RequestHandlerBase$handleRequest###################################org.apache.solr.core.SolrCore$execute###################################org.apache.solr.servlet.HttpSolrCall$execute###################################org.apache.solr.servlet.HttpSolrCall$call###################################org.apache.solr.servlet.SolrDispatchFilter$doFilter###################################org.apache.solr.servlet.SolrDispatchFilter$doFilter###################################org.eclipse.jetty.servlet.ServletHandler$CachedChain$doFilter###################################org.eclipse.jetty.servlet.ServletHandler$doHandle###################################org.eclipse.jetty.server.handler.ScopedHandler$handle###################################org.eclipse.jetty.security.SecurityHandler$handle###################################org.eclipse.jetty.server.session.SessionHandler$doHandle###################################org.eclipse.jetty.server.handler.ContextHandler$doHandle###################################org.eclipse.jetty.servlet.ServletHandler$doScope###################################org.eclipse.jetty.server.session.SessionHandler$doScope###################################org.eclipse.jetty.server.handler.ContextHandler$doScope###################################org.eclipse.jetty.server.handler.ScopedHandler$handle###################################org.eclipse.jetty.server.handler.HandlerWrapper$handle###################################org.eclipse.jetty.server.Server$handle###################################org.eclipse.jetty.server.HttpChannel$handle###################################org.eclipse.jetty.server.HttpConnection$onFillable###################################org.eclipse.jetty.io.AbstractConnection$ReadCallback$succeeded###################################org.eclipse.jetty.io.FillInterest$fillable###################################org.eclipse.jetty.io.SelectChannelEndPoint$2$run###################################org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume$executeProduceConsume###################################org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume$produceConsume###################################org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume$run###################################org.eclipse.jetty.util.thread.QueuedThreadPool$runJob###################################org.eclipse.jetty.util.thread.QueuedThreadPool$2$run###################################java.lang.Thread$run 異常方式 Exception e=new Exception(); e.printStackTrace(); 舉例: @Override public SimWeight computeWeight(float boost, CollectionStatistics collectionStats, TermStatistics... termStats) { Exception e=new Exception(); e.printStackTrace(); /* java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces(); StackTraceElement[] ste = ts.get(Thread.currentThread()); for (StackTraceElement s : ste) { System.out.println('###################################'+s.getClassName()+'$'+s.getMethodName()); } */ //業(yè)務邏輯 return new DavidStats(field,K_length,KE_length, termStats) ; } 打印情況 java.lang.Exception at org.apache.lucene.search.similarities.DavidSimilarity.computeWeight(DavidSimilarity.java:91) at org.apache.lucene.search.TermQuery$TermWeight.<init>(TermQuery.java:75) at org.apache.lucene.search.TermQuery.createWeight(TermQuery.java:205) at org.apache.lucene.search.IndexSearcher.createWeight(IndexSearcher.java:738) at org.apache.lucene.search.BooleanWeight.<init>(BooleanWeight.java:56) at org.apache.lucene.search.BooleanQuery.createWeight(BooleanQuery.java:208) at org.apache.lucene.search.IndexSearcher.createWeight(IndexSearcher.java:738) at org.apache.lucene.search.IndexSearcher.createNormalizedWeight(IndexSearcher.java:727) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:462) at org.apache.solr.search.SolrIndexSearcher.buildAndRunCollectorChain(SolrIndexSearcher.java:215) at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:1602) at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:1417) at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:584) at org.apache.solr.handler.component.QueryComponent.doProcessUngroupedSearch(QueryComponent.java:1435) at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:375) at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:295) at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:177) at org.apache.solr.core.SolrCore.execute(SolrCore.java:2503) at org.apache.solr.core.QuerySenderListener.newSearcher(QuerySenderListener.java:74) at org.apache.solr.core.SolrCore.lambda$17(SolrCore.java:2275) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.solr.common.util.ExecutorUtil$MDCAwareThreadPoolExecutor.lambda$0(ExecutorUtil.java:188) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) 3.通過時序圖將上面的調用鏈路畫出來(示例,非嚴格按照上面的邏輯) 總結: 閱讀源碼總體上是一個長期的過程,每次閱讀想要有所收獲,就需要留下一些東西,比如有人寫博客,有人記日志等等,如果不做任何準備,盲目的去閱讀代碼,往往今天讀明天忘,浪費了大量的時間反而沒有相應的收獲。 通過梳理調用鏈的方式可以加深對源碼的理解,通過流程圖的梳理,讓下次源碼閱讀更有效率,有圖有真相。 |
|