2016-03-19 44 views
0

我們正在尋找一種解決方案來以高性能的方式跟蹤客戶端POJO實例的狀態。我們期望的是:每次在POJO上進行更改時,都會使用setter來進行此狀態。我們創建了基於OGNL的觀看/事件總線,當發生變化時,我們將發送適當的OgnlChangeEvent到我們的事件總線。如何使用代碼生成跟蹤POJO的狀態

到目前爲止,我們研究了AspectJ/cglib/object graph Diff解決方案,但它們都佔用了太多的CPU時間。我們目前的解決方案基於Spring MethodInterceptor,並且每次調用Getter方法時我們都會創建一個新的Proxy實例。

在這一點上,我們開始看代碼生成解決方案,我們偶然發現了Byte Buddy。這個方向是否是正確的方式?我們是否可以生成一個新的Class,它將擴展我們的客戶端POJO狀態並通知其OGNL前綴,直到調用setter方法爲止?

+0

你能詳細說明一些測量的性能問題嗎?您調用方法的次數,沒有更改跟蹤的方法執行時間是多少,更改跟蹤的執行時間是多少,以及您在代碼的更改跟蹤部分中執行的操作的概述? –

+0

我同意@NándorElődFekete。很難相信AspectJ應該比Spring AOP慢。如果是這樣,你必須做一些錯誤的事情,因爲AspectJ非常高效。如果我們看到你的方面,也許我們可以幫助。但是如果你對ByteBuddy感到滿意,也許這個評論已經過時了。我最近在這裏沒有讀過很多東西,因爲我很忙,所以我在這裏評論有點遲,也許。 – kriegaex

回答

2

Byte Buddy是一個代碼生成工具,它當然可以實現這樣的解決方案。爲了創建一個截取一個二傳手的一類,你會寫這樣的代碼:

new ByteBuddy() 
    .subclass(UserPojo.class) 
    .method(ElementMatchers.isSetter()) 
    .intercept(MethodDelegation.to(MyInterceptor.class) 
      .andThen(SuperMethodCall.INSTANCE) 
    .make(); 

在那裏你會寫這樣一個攔截器:

public class MyInterceptor { 
    public static void intercept(Object value) { 
    // business logic comes here 
    } 
} 

這樣一來,每次都可以添加一些代碼二傳手在原始代碼之前被觸發。您還可以使用所有基元類型重載攔截方法,以避免對參數進行裝箱。 Byte Buddy指出爲你做什麼。

但是,我很困惑你的意思是性能。上面的代碼就我一樣創建一個類,如:

class UserClass { 
    String value; 
    void setValue(String value) { 
    this.value = value; 
    } 
} 

class InstrumentedUserClass extends UserClass { 
    @Override 
    void setValue(String value) { 
    MyInterceptor.intercept(value); 
    super.setValue(value); 
    } 
} 

性能主要是由你的intercept方法中做了什麼性能的影響。

最後,我不明白cglib如何不適合你,但使用Spring - 它建立在cglib之上 - 是行得通的。我懷疑你應該研究一下你的攔截邏輯有一些問題。

+0

謝謝:-) CGLIB正在爲我工​​作,以及春季包裝解決方案。主要的問題是,並且仍然是性能:-( –

1

我認爲性能並不取決於您使用的字節碼檢測框架,而是取決於您在方法攔截器中所做的工作。最後,你只會知道你是否測量。

我不知道很多關於你的使用情況,但一般我會問自己:

  • 我真的需要什麼樣的信息?
  • 從中獲取這些信息的基本數據是什麼?

您應該將基本數據收集與該數據(信息)的解釋分開。通常解釋需要更多時間。基本數據是無法從其他數據導出的數據。生日是基本數據,而年齡來自生日。

在方法攔截我會

  • 只收集像類名,方法名和參數可能的基本數據。
  • 將此信息發送給某種工作隊列
  • 讓後臺工作人員生成信息,記錄或保留它。

背景工作者可以例如解釋方法名稱以找出它是否是屬性存取器。通常你使用從Introspector或至少反射api得到的BeanInfo來做到這一點。

+0

感謝René!最耗費的部分是爲每個getter方法創建新的代理以便繼續獲得Ognl前綴,這就是爲什麼我尋找字節檢測解決方案的原因。 –