歡迎光臨
每天分享高質量文章

Java Web技術經驗總結(十二)

1. 優先順序佇列

今天解決多執行緒問題的時候,用到了優先順序佇列模型,涉及到“按照優先順序”從高到低遍歷,因此查到這個問題:如何利用Java原因逆序遍歷一個TreeMap?參考連結:http://beginnersbook.com/2014/07/how-to-iterate-treemap-in-reverse-order-in-java/

  1. import java.util.*;

  2. class TreeMapDemo {

  3.    public static void main(String args[]) {

  4.        Map<String, String> treemap =

  5.            new TreeMap<String, String>(Collections.reverseOrder());

  6.        // Put elements to the map

  7.        treemap.put("Key1", "Jack");

  8.        treemap.put("Key2", "Rick");

  9.        treemap.put("Key3", "Kate");

  10.        treemap.put("Key4", "Tom");

  11.        treemap.put("Key5", "Steve");

  12.        Set set = treemap.entrySet();

  13.        Iterator i = set.iterator();        // Display elements

  14.        while(i.hasNext()) {

  15.            Map.Entry me = (Map.Entry)i.next();

  16.            System.out.print(me.getKey() + ": ");

  17.            System.out.println(me.getValue());

  18.        }

  19.    }

  20. }

2. 可重入鎖ReetrantLock

在Java中,使用ReetrantLock作為互斥鎖,使用Condition作為通知機制,支援多路通知。參考一篇文章:http://www.cnblogs.com/xrq730/p/4855155.html

3. greys,生產環境debug的利器

預發/線上的遠端debug利器greys:在Java開發中,如果服務部署在日常環境,我們可以透過IDEA 的遠端DEBUG功能進行單步跟蹤;但是如果線上服務出現問題,需要快速在預發環境復現問題的時候,並不能單步跟蹤,這時候可以使用greys。利用greys可以實現類似BTrace的功能,打印出某個介面的呼叫鏈、可以打印出某個方法的呼叫情況和入參。

4. Collections.emptyMap()的使用場景?

近期在CodeReview的時候發現有同學試圖給Collections.emptyMap()的傳回值put值,從而引發錯誤。其實檢視原始碼就可以知道,該介面傳回的是一個不可變的EmptyMap物件。在《Effective Java》一書中指出,這個介面的作用是:“在能傳回陣列的情況下,不要傳回null”,即為了避免傳回null值,從而使得上層呼叫不需要檢查傳回值是否為null。參考stackoverflow上的問答:http://stackoverflow.com/questions/14846920/collections-emptymap-vs-new-hashmap

5. 經驗總結

近期遇到一個異常:“Caused by: java.lang.IllegalStateException: Duplicate spring bean id realnameAuthPubService ” 之前閱讀Spring原始碼的時候知道,在Spring 中支援xml檔案的重覆匯入,參考DefaultListableBeanFactory類的這個方法。可以看出,根據allowBeanDefinitionOverriding這個標誌位的設定,Spring 也可以配置成不允許重覆掃描xml。

  1. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {

  2.    Assert.hasText(beanName, "Bean name must not be empty");

  3.    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

  4.    if(beanDefinition instanceof AbstractBeanDefinition) {

  5.        try {

  6.            ((AbstractBeanDefinition)beanDefinition).validate();

  7.        } catch (BeanDefinitionValidationException var7) {

  8.            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var7);

  9.        }

  10.    }

  11.    Map var4 = this.beanDefinitionMap;

  12.    BeanDefinition oldBeanDefinition;

  13.    synchronized(this.beanDefinitionMap) {

  14.        oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);

  15.        if(oldBeanDefinition != null) {

  16.            if(!this.allowBeanDefinitionOverriding) {

  17.                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean \'" + beanName + "\': There is already [" + oldBeanDefinition + "] bound.");

  18.            }

  19.            if(this.logger.isInfoEnabled()) {

  20.                this.logger.info("Overriding bean definition for bean \'" + beanName + "\': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

  21.            }

  22.        } else {

  23.            this.beanDefinitionNames.add(beanName);            this.frozenBeanDefinitionNames = null;

  24.        }

  25.        this.beanDefinitionMap.put(beanName, beanDefinition);

  26.    }

  27.    if(oldBeanDefinition != null || this.containsSingleton(beanName)) {

  28.        this.resetBeanDefinition(beanName);

  29.    }

  30. }

而我們遇到的問題是Dubbo框架在啟動時引發的異常,檢視Dubbo的原始碼可以發現,Dubbo 3.0之後改了策略,不允許bean的重覆定義。這個問題是參考Duplicate spring bean id問題排查(http://blog.csdn.net/wanyanxgf/article/details/6944762#0-tsina-1-53377-397232819ff9a47a7b7e80a40613cfe1)這篇文章解決的。

6. 使用Spring AOP進行日誌記錄

對於某個類中的方法,如果這個方法不是實現其對應的介面的方法,則不能使用基於介面的代理。即必須使用基於類的代理樣式,也就是說,對應的Spring AOP的配置檔案應該為:

  1. proxy-target-class="true"/>

  2. base-package="com.*.*.*.example" />

7. Java中的介面回呼

深入淺出Java回呼機制 和 回呼函式。
今天遇到一個問題,應用A和應用B共用了同一套底層程式碼L,業務需要在執行L中的某個函式的時候給呼叫B中的一個方法,對於B來說,只需要本地函式呼叫即可;對於A來說,則需要透過RPC呼叫實現,但是L只有一種實現,因此不能寫死。這時候可以利用Java的回呼機制,將具體的呼叫邏輯作為一個回呼介面傳入到L中。這樣A和B可以自由選擇自己對L的呼叫策略。

8. git忽略已經跟蹤的檔案

在使用git過程中,有時候需要排除某個已經被跟蹤的檔案,這時候可以使用命令: git rm--cached logs/xx.log。參考:git忽略已經跟蹤的檔案

9. redis的使用技巧

DEL命令不支援萬用字元,但是我們可以結合Linux的管道和xargs命令自己實現刪除所有符合規則的鍵。比如要刪除所有以”bar”開頭的鍵,就可以執行 redis-cli KEYS"bar*"|xargs DEL命令。另外,由於DEL命令支援多個鍵作為引數,所以還可以用命令 redis-cli DELredis-cli KEYS “bar*”“,後者效率更高。

最後做個投票,這個號後面的發展,有你的一份努力:

贊(0)

分享創造快樂