如何使用 AspectJ 完成加载时织入 .jar 文件?

How is Load-Time Weaving to a .jar file with AspectJ done?

一些项目背景:我正在使用在 Java 上运行的应用程序。我的目标是收集实时数据并将其发送到本地服务器上的 API 运行。该应用程序被打包到一个 .jar 文件中,我无法访问源代码。 (除了这个问题,我还试图反编译 class 以添加额外的功能;然而,结果并不好,$access000...)

刚刚了解了 AOP,我 运行 测试了我的选择。我花了一个多星期的时间来弄清楚 Maven Setup 和 AspectJ。

我建立了一个“helloworld”项目,在该项目中我已经能够成功地将方面(从 .java 文件)编织到另一个 .java 文件中。我的下一步是创建一个包含主要 class 的可执行 .jar 文件,并将方面 .java class 编织到其中 - 然后我就会实现我想要的结果。

是否可以将预编译的.jar文件放入项目中并为其编写方面?

我不确定我是否误解了什么,我相信那应该是可行的。

来自 AspectJ 开发环境指南:

In AspectJ tools, the aspectpath is where to find binary aspects. Like the classpath, it can include archives ( .jar and .zip files) and directories containing .class files in a package layout (since binary aspects are in .class files).

一些参考资料:

项目结构

├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── hellomaven
    │               └── quickstart
    │                   ├── App.java
    │                   └── AppAspect.java
    └── test
        ├── java
        └── resources

POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.hellomaven</groupId>
  <artifactId>quickstart</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>helloMaven</name>
  <description>test</description>

  <properties>
    <java.version>1.8</java.version>
    <junit.version>4.5</junit.version>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>

  <build>
    <pluginManagement>
      <plugins>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.9</version>
          <configuration>
            <showWeaveInfo>true</showWeaveInfo>
            <source>${java.version}</source>
            <target>${java.version}</target>
            <Xlint>ignore</Xlint>
            <complianceLevel>${java.version}</complianceLevel>
            <encoding>UTF-8</encoding>
            <verbose>true</verbose>
            <weaveDependencies>
              <weaveDependency>
                <groupId>com.hellomaven.quickstart.App</groupId>
                <artifactId>hello</artifactId>
              </weaveDependency>
            </weaveDependencies>
          </configuration>
          <executions>
            <execution>
              <phase>process-sources</phase>
              <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
              </goals>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjrt</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjtools</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
          </dependencies>
        </plugin>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.3</version>
          <configuration>
            <mainClass>com.hellomaven.quickstart</mainClass>
          </configuration>
        </plugin>

      </plugins>
    </pluginManagement>
  </build>
</project>

App.java

package com.hellomaven.quickstart;

public class App {
    public static void main(String[] args) {
        hello("World");
    }
    
    public static void hello(String world) {
        System.out.println("Hello " + world);
    }
}

AppAspect.java

package com.hellomaven.quickstart;

import org.aspectj.lang.annotation.*;

@Aspect
public class AppAspect {
    
    @Before("execution(public static void hello(..))")
    public void testAspectBefore() {
        System.out.println("Before ok.");
    }
}

无论您在何处以何种方式编写 运行 代码,您只需将 -javaagent:/path/to/aspectjweaver.jar 添加到 Java 命令行即可。此外,对于 LTW,您需要在正确的位置使用 aop.xml。对于 Maven,这意味着:

  • aop.xml 应该位于 src/main/resources.
  • 如果您在 JUnit 测试中需要 LTW,则需要将 -javaagent 参数添加到您的 Surefire 插件(单元测​​试)或 Failsafe 插件(集成测试)配置中。
  • 如果你想使用 Exec Maven 插件启动你编译的程序,似乎是这种情况,你也需要在插件配置中添加 -javaagent 参数。

在 Maven 之外,您需要再次将 -javaagent 添加到命令行。

很抱歉回答笼统,但这只是您的笼统问题的反映。如果你有更精确的follow-up问题,你可以评论这个答案。

部分资源: