【问题标题】:Using AspectJ annotations without Spring在没有 Spring 的情况下使用 AspectJ 注释
【发布时间】:2017-09-03 11:03:44
【问题描述】:

我对 AOP 还很陌生。我正在尝试使用 AspectJ 在没有 Spring 的 Maven 项目中创建注释。但是我尝试使用@Aspect 调用的方法没有被调用。

这就是我的 pom 的样子:

<?xml version="1.0" encoding="UTF-8"?>

<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>test</groupId>
<artifactId>tanvi</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
    <!-- https://mvnrepository.com/artifact/aspectj/aspectjrt -->
    <dependency>
        <groupId>aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.5.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/aspectj/aspectjweaver -->
    <dependency>
        <groupId>aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.5.3</version>
    </dependency>
    <dependency>
        <groupId>aspectj</groupId>
        <artifactId>aspectjtools</artifactId>
        <version>1.5.3</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.8</version>
            <configuration>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
            <executions>
                <execution>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

注解如下所示:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface HasAccess {
    Access[] accesses();
    String message() default "You are not allowed to perform this operation";
}

我为我的注释创建了一个注释处理器:

@Aspect
public class HasAccessAdvice {
    //    @Before("execution(* *.*(..)) && @annotation(testAnnotation) ")
    @Before("execution(* *.*(..)) && @annotation(hasAccess)")
    public void myBeforeLogger(JoinPoint joinPoint, HasAccess hasAccess) {

    System.out.println("Okay - we're in the before handler...");
    System.out.println("The test annotation value is: " + hasAccess.accesses().toString());

    Signature signature = joinPoint.getSignature();
    String methodName = signature.getName();
    String stuff = signature.toString();
    String arguments = Arrays.toString(joinPoint.getArgs());
    System.out.println("Write something in the log... We are just about to call method: "
                       + methodName + " with arguments " + arguments + "\nand the full toString: "
                       + stuff);

}

}

我在这次通话中调用它:

public class TestMe {

    @HasAccess(accesses = {Access.CREATE_PURCHASE})
    public void createPurchase(BigDecimal bigDecimal) {
        System.out.println("create Purchase called");
    }
}

我创建了一个 aop.xml 文件并将它放在与 pom.xml 相同的文件夹中。

<aspectj>
    <aspects>
        <aspect name="HasAccessAdvice"/>
    </aspects>
</aspectj>

当我调用 createPurchase 方法时,它会在没有首先调用 @Before 方法的情况下运行。请帮助我解决我所缺少的。我发现的大多数文档/答案都是 Spring 对齐的。任何指向任何教程的指针,甚至是在没有 Spring 的情况下创建简单注释的另一种方法都将不胜感激。

【问题讨论】:

  • 你是如何运行你的代码的?

标签: java maven annotations aop aspectj


【解决方案1】:

首先,由于您使用的是aop.xml,我假设您想要进行加载时间编织。请参阅Load Time Weaving docsdocs on different weaving types

其次,在aop.xml 文件中,定义要使用的&lt;aspect&gt;,但还需要定义要编织的类文件/包:

<aspectj>
    <aspects>
        <aspect name="HasAccessAdvice"/>
    </aspects>
    <weaver options="-verbose">
        <!-- weave anything -->
        <include within="*" />
        <!-- weave specific packages only -->
        <include within="my.package..*" />
    </weaver>    
</aspectj>

要么使用"*" 在任何类上运行你的方面,要么将my.package 替换为TestMe 的包。请注意,双点 .. 也包含子包。
另请注意,&lt;aspect name="..."&gt; 要求带有包的完全限定的 Aspect-name。您是否在默认包中创建了HasAccessibleAdvice?否则添加你的包。

第三,aop.xml 必须在您的类路径上的 META-INF/aop.xml 中可读。
如果您通过 CLI 运行测试(使用 java -javaagent...),请检查您的类路径设置 (-cp)。
如果您正在编写 JUnit 测试,您可以将 META-INF/aop.xml 放入 src/test/resources 并调整您的 pom.xml&lt;build&gt;&lt;plugins&gt; 部分以包含加载时间编织器,如下所示:

<properties>
    <aspectj.version>1.8.9</aspectj.version>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <argLine>
                    -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
                </argLine>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2016-12-04
    • 1970-01-01
    • 2012-08-04
    相关资源
    最近更新 更多