簡體   English   中英

使用字節伙伴代理按AspectJ檢測編織的類

[英]Detect weaved class by aspectJ with byte-buddy agent

我想驗證代碼是否由AspectJ編寫。 我聽說過的一種方法是使用字節伙伴庫中的代理。 不幸的是,我完全是綠色的,我不知道該怎么辦。

我嘗試將JADE與代理一起使用,但是字節伙伴對我自己更友好,我認為它更合適。

為了驗證該方法,我創建了一個帶有MySQL連接的簡單springboot應用程序,並添加了一些AspectJ代碼。 我嘗試使用Spring AOP,但是AOP無法讀取私有方法,因此我決定將我的想法提供給AspectJ。

我已經使用了另一個方面來定義joinPoints並引發異常,但是這很困難並且需要大量工作並且結果很低。

您對使用字節伙伴來檢測AspectJ的代理的方法或實現有任何想法嗎?

首先回答您的評論:

我想對不可信的代碼有更多的經驗。 例如,如果我用Java開發了一個大型項目,然后得到了一個由AspectJ創建的更改的不受信任的插件,那么我更願意知道該怎么做才能檢查我的類是否受AspectJ的保護或AspectJ只是編織到我的類中。

對於AspectJ,有兩種情況:

  • 編譯時編織

    • 您的應用程序不使用AspectJ,在Maven構建中沒有使用AspectJ Maven插件,在Gradle構建中也沒有類似的東西:即使您的第三方庫位於類路徑中,也沒有任何東西編入您自己的代碼中。 怎么可能 沒有AspectJ編譯器。
    • 您的應用程序使用AspectJ編譯器:即使第三方庫位於類路徑中,也沒有將方面編織到您自己的代碼中,因為您必須將庫明確地放在方面路徑中才能實現。 順便說一句,如果第三方庫是方面增強的,它將依賴於AspectJ運行時Aspectjrt.jar ,否則它將無法工作。 即使運行時被隱藏在其他JAR中,您自己的代碼也不會發生任何事情。
  • 加載時間編織

    • 您的應用程序不使用LTW:顯然什么也不會發生,如果您不使用活動的編織代理啟動JVM,則其他JAR的任何方面都無法編織到您的代碼中。
    • 您的應用程序使用LTW:您將需要提供aop.xml文件,在這里您可以顯式列出要應用的方面,哪些目標類或包要包含在編織中或從編織中排除,請打開-showWeaveInfo以便也能看到控制台將哪些方面編織到哪些連接點中。 但是,有一個警告:如果AspectJ編織者在類路徑上找到多個aop.xmlaop-ajc.xml文件,它將在概念上進行合並。 即,如果第三方庫隨附了這樣的文件,則該文件將按照AspectJ開發指南中的說明合並到您自己的文件中(在頁面上搜索“多個配置文件”)。 因此,這可能會導致一些不良后果。 如果要檢查第三方庫,最簡單的操作是分別掃描JAR中是否存在aop.xmlaop-ajc.xml 然后,您可以查看這些文件的內容(如果有),並輕松評估它們對代碼的可能影響。 但是,只要在應用程序啟動時檢查-showWeaveInfo的輸出,還可以發現是否將不需要的方面編織到了自己的代碼中。

因此,實際上,您不需要掃描類文件中的任何內容即可檢測AspectJ標記,但是如果您絕對希望這樣做,可以執行以下操作:

大多數AspectJ編織的類都包含字段或方法(可以是靜態或非靜態,私有或公共的),其名稱中的ajc$通常在開頭。 那只是一種啟發式方法,但是嘿-不管用什么,對不對?

  • 如果我說“大多數類”,我的意思是在某些情況下,如果某個方面僅使用ITD來使一個類實現接口,引入新方法或公共字段,則該類將僅獲取新元素,而沒有AspectJ專用代碼。 但那時它們只是普通的類,沒有交叉的建議代碼或任何可能影響您自己的應用程序的代碼。
  • 如果找到這樣的成員或字段,則表明您或者找到了由方面增強的類(即使在帶有額外aop.xml的LTW場景中也不會影響您自己的類)或方面本身,因為它們還包含相同的標記,您可以掃描的其他一些東西。

那么,如何掃描這些第三方類文件?

  • 命令行: javap -p path/to/MyClass.class | grep 'ajc[$]' javap -p path/to/MyClass.class | grep 'ajc[$]'
  • 掃描已經加載到您的(測試或檢查)應用程序中的類的Java代碼:
package de.scrum_master.aspect;

import java.lang.reflect.Member;
import java.util.stream.Stream;

public class AspectJDetector {
  public static boolean hasAspectJMarker(Class<?> clazz) {
    return Stream.concat(
      Stream.of((Member[]) clazz.getDeclaredMethods()),
      Stream.of((Member[]) clazz.getDeclaredFields())
    )
      .filter(member -> member.getName().contains("ajc$"))
      .findFirst()
      .isPresent();
  }
}

只需為要檢查的每個類調用hasAspectJMarker(MyClassOfInterest.class) 如果找到了AspectJ增強的類,則無需擔心。 只有找到方面,才有可能。 但是正如我上面所說:通過該JAR中的aop.xml可以更容易地檢測到它。 XML文件甚至可以通過<aspect name="com.MyAspect"/>顯式列出方面,這基本上是顯而易見的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM