2009-11-10 98 views
17

我正嘗試使用一個使用CGLIB創建代理對象的AOP框架來創建一個對象。 奇怪的是,「增強」代理對象沒有任何前一課的註釋!保留CGLIB代理上的註釋?

誰能告訴我如何讓CGLIB保留它創建的代理上的註釋?

乾杯! Nirav

+0

@Inherited註釋是否解決了問題?如果是這樣,你可以考慮批准答案。謝謝。 – noego 2015-02-15 20:08:52

+0

'@ Inherited'不能解決問題(我自己試過)。就我個人而言,我使用的是一個Spring項目,並通過使用AnnotationUtils實用程序類來解決,因此您可以看到[這裏](https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main /java/org/springframework/core/annotation/AnnotationUtils.java)它是如何工作的。 – Alessio 2016-09-28 16:43:34

回答

5

這不是「保留」註釋的問題。 CGLIB代理實際上是目標對象類的子類。這些子類可能沒有註釋,但是他們的超類(即你自己的類)仍然有它們。您使用的任何註釋反映代碼都需要能夠回顧類層次結構以查找註釋。

3

這是一個有效的問題(我現在正在進入自己)a)並非所有的框架都足夠聰明來檢查父類b)即使它們足夠聰明,它們也可能選擇不這樣做。後者似乎是Guice的情況。 FWIW,https://issues.apache.org/jira/browse/WICKET-1130是我在研究時發現的問題。

15

CGLIB創建給定類的子類來生成代理。除非在註解定義中明確指定,否則註釋不會保留在子類中。 @Inherited註釋用於此目的。

您可以使用此批註中定義的註釋,並讓他們在子類中訪問,如下:

@Inherited 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface MyAnnotation { 
} 
+0

我遇到此問題,而且看起來您的修補程序沒有正常工作。 – 2016-01-14 20:06:59

+0

@Inherited爲我工作。謝謝 – 2017-02-21 21:37:41

+0

@Inherited僅當註解的目標是一個類時才起作用 - 你的子類代理的方法仍然沒有註釋。 – Phil 2018-03-10 07:23:36

3

CGLIB是不是能夠保持註釋不改變它的內部實現的。然而,這很複雜,我相信我嘗試過。我終於想出了我的修改版本,但是如此複雜,我決定實施Byte Buddy,這是另一個具有這種功能的代碼生成庫。

下面是如何創建的子類,

@Retention(RetentionPolicy.RUNTIME) 
@interface MyAnnotation { } 

@MyAnnotation 
class MyClass { } 

assertThat(new ByteBuddy() 
    .subclass(Object.class) 
    .attribute(TypeAttributeAppender.ForSuperType.INSTANCE) 
    .make() 
    .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) 
    .getLoaded() 
    .isAnnotationPresent(MyAnnotation.class), is(true)); 

字節巴迪配備了一個廣泛的全文文檔和javadoc一個例子,這是很容易擴展。希望你能很好地利用圖書館。