简体   繁体   English

AspectJ:如何将方面库编织到 Java 项目中

[英]AspectJ: How to weave an aspect library into a Java project

I build small library (Java and Maven) - using AspectJ.我使用 AspectJ 构建小型库(Java 和 Maven)。 Library must be independent.图书馆必须是独立的。 Library deliver Aspects and Annotations.库提供方面和注释。 Function of library is - "call advice when executed a method with specific annotation".库的功能是-“执行具有特定注释的方法时调用建议”。 All is ok when I use everything in one module, but problem appers when i separate library and project with classes which advice must be applied.当我在一个模块中使用所有内容时一切正常,但是当我将库和项目与必须应用建议的类分开时,问题就会出现。 I create simple schema.我创建了简单的模式。 架构 Library B - my library (aspects and annotations) Project A - project with buisness methods which adivce must be applied Is any posibility to do this?图书馆 B - 我的图书馆(方面和注释) 项目 A - 必须应用商业方法的项目 是否有可能做到这一点?

According to the AspectJ Maven documentation, chapter "using aspect libraries" , you need to根据AspectJ Maven 文档,“使用方面库”一章,您需要

  • add the aspect library as a regular <dependency> ,添加方面库作为常规<dependency>
  • also add the same dependency (without <version> because it is already assigned in step 1) in the plugin <configuration><aspectLibraries> section as an <aspectLibrary> .还在插件<configuration><aspectLibraries>部分添加相同的依赖项(没有<version>因为它已经在步骤 1 中分配了)作为<aspectLibrary>

Here is a concrete example:下面是一个具体的例子:

Aspect library POM, marker annotation and sample aspect:方面库 POM、标记注释和示例方面:

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>de.scrum-master.stackoverflow</groupId>
    <artifactId>aspectj-lib</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>AspectJ Library</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.source-target.version>1.8</java.source-target.version>
        <aspectj.version>1.8.7</aspectj.version>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.3</version>
                    <configuration>
                        <source>${java.source-target.version}</source>
                        <target>${java.source-target.version}</target>
                        <!-- IMPORTANT -->
                        <useIncrementalCompilation>false</useIncrementalCompilation>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.7</version>
                    <configuration>
                        <!--<showWeaveInfo>true</showWeaveInfo> -->
                        <source>${java.source-target.version}</source>
                        <target>${java.source-target.version}</target>
                        <Xlint>ignore</Xlint>
                        <complianceLevel>${java.source-target.version}</complianceLevel>
                        <encoding>${project.build.sourceEncoding}</encoding>
                        <!--<verbose>true</verbose> -->
                        <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn> -->
                    </configuration>
                    <executions>
                        <execution>
                            <!-- IMPORTANT -->
                            <phase>process-sources</phase>
                            <goals>
                                <goal>compile</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>org.aspectj</groupId>
                            <artifactId>aspectjtools</artifactId>
                            <version>${aspectj.version}</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
            </plugin>
            <!--
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            -->
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
    </dependencies>

    <organization>
        <name>Scrum-Master.de - Agile Project Management</name>
        <url>http://scrum-master.de</url>
    </organization>

</project>
package de.scrum_master.aspect;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Marker {}
package de.scrum_master.aspect;

public aspect MyAspect {
    before() : execution(* *(..)) && @annotation(Marker) {
        System.out.println(thisJoinPoint);
    }
}

Now run mvn clean install on the aspect library project so as to install the dependency into your local Maven repo.现在在方面库项目上运行mvn clean install以便将依赖项安装到本地 Maven 存储库中。

Java application POM and sample application: Java 应用程序 POM 和示例应用程序:

By the way, in the POM I have also added two optional plugins:顺便说一下,在 POM 中我还添加了两个可选插件:

  • One-JAR plugin packages your application with all dependencies (eg aspect library and AspectJ runtime) into one artifact, here target/java-app-0.0.1-SNAPSHOT.one-jar.jar . One-JAR 插件将您的应用程序与所有依赖项(例如方面库和 AspectJ 运行时)打包到一个工件中,这里是target/java-app-0.0.1-SNAPSHOT.one-jar.jar You can just run your application via java -jar target/java-app-0.0.1-SNAPSHOT.one-jar.jar .您可以通过java -jar target/java-app-0.0.1-SNAPSHOT.one-jar.jar运行您的应用程序。
  • Exec Maven plugin is useful if you easily want to test your application from the command line via mvn clean install exec:java .如果您想通过mvn clean install exec:java从命令行轻松测试您的应用程序,Exec Maven 插件非常有用。

These two are only for convenience, you do not need them if you dislike them.这两个只是为了方便,如果你不喜欢它们,你不需要它们。

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>de.scrum-master.stackoverflow</groupId>
    <artifactId>java-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>Java Application</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.source-target.version>1.8</java.source-target.version>
        <aspectj.version>1.8.7</aspectj.version>
        <main-class>de.scrum_master.app.Application</main-class>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.3</version>
                    <configuration>
                        <source>${java.source-target.version}</source>
                        <target>${java.source-target.version}</target>
                        <!-- IMPORTANT -->
                        <useIncrementalCompilation>false</useIncrementalCompilation>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.7</version>
                    <configuration>
                        <!--<showWeaveInfo>true</showWeaveInfo> -->
                        <source>${java.source-target.version}</source>
                        <target>${java.source-target.version}</target>
                        <Xlint>ignore</Xlint>
                        <complianceLevel>${java.source-target.version}</complianceLevel>
                        <encoding>${project.build.sourceEncoding}</encoding>
                        <!--<verbose>true</verbose> -->
                        <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn> -->
                        <aspectLibraries>
                            <aspectLibrary>
                                <groupId>de.scrum-master.stackoverflow</groupId>
                                <artifactId>aspectj-lib</artifactId>
                            </aspectLibrary>
                        </aspectLibraries>
                    </configuration>
                    <executions>
                        <execution>
                            <!-- IMPORTANT -->
                            <phase>process-sources</phase>
                            <goals>
                                <goal>compile</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <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.4.0</version>
                    <configuration>
                        <mainClass>${main-class}</mainClass>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.dstovall</groupId>
                    <artifactId>onejar-maven-plugin</artifactId>
                    <version>1.4.4</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>one-jar</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <onejarVersion>0.96</onejarVersion>
                        <mainClass>${main-class}</mainClass>
                        <attachToBuild>true</attachToBuild>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
            </plugin>
            <!--
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <configuration>
                    <mainClass>${main-class}</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.dstovall</groupId>
                <artifactId>onejar-maven-plugin</artifactId>
                <configuration>
                    <mainClass>${main-class}</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <pluginRepositories>
        <pluginRepository>
            <id>OneJAR googlecode.com</id>
            <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
        </pluginRepository>
    </pluginRepositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>de.scrum-master.stackoverflow</groupId>
                <artifactId>aspectj-lib</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
            <dependency>
                <groupId>de.scrum-master.stackoverflow</groupId>
                <artifactId>aspectj-lib</artifactId>
            </dependency>
    </dependencies>

    <organization>
        <name>Scrum-Master.de - Agile Project Management</name>
        <url>http://scrum-master.de</url>
    </organization>

</project>

This little driver application demonstrates that you can now annotate methods with @Marker , in this case only foo and zot , but not bar :这个小驱动程序应用程序演示您现在可以使用@Marker注释方法,在这种情况下只有foozot ,而不是bar

package de.scrum_master.app;

import de.scrum_master.aspect.Marker;

public class Application {
    @Marker
    public static void foo() {}

    public static void bar() {}

    @Marker
    public static void zot() {}

    public static void main(String[] args) {
        foo();
        bar();
        zot();
    }
}

Console log:控制台日志:

java -jar target/java-app-0.0.1-SNAPSHOT.one-jar.jar

execution(void de.scrum_master.app.Application.foo())
execution(void de.scrum_master.app.Application.zot())

Here is a short summary of krigaex's answer.这是krigaex答案的简短摘要 Add your library as a normal dependency and as an AspectJ plugin dependency to pom.xml .将您的库作为普通依赖项和AspectJ插件依赖项添加到pom.xml If you use com.nickwongdev:aspectj-maven-plugin - use <weaveDependencies> & <weaveDependency> tags instead of <aspectLibraries> & <aspectLibrary> :如果您使用com.nickwongdev:aspectj-maven-plugin - 使用<weaveDependencies> & <weaveDependency>标签而不是<aspectLibraries> & <aspectLibrary>

<project>
  <dependencies>
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>my-library</artifactId>
      <version>1.2.0-SNAPSHOT</version>
    </dependency>
  <build>
    <plugins>
    <plugin>
      <groupId>com.nickwongdev</groupId>
      <artifactId>aspectj-maven-plugin</artifactId>
      <version>1.12.6</version>
      <configuration>
        <weaveDependencies>
          <weaveDependency>
            <groupId>com.example</groupId>
            <artifactId>my-library</artifactId>
          </weaveDependency>
        </weaveDependencies>
      </configuration>
    </plugin>
    </plugins>
  </build>
</project>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM