首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不工作的AspectJ示例的实现

不工作的AspectJ示例的实现
EN

Stack Overflow用户
提问于 2022-05-23 07:29:10
回答 1查看 201关注 0票数 0

我尝试从AspectJ实现一个简单的https://www.baeldung.com/aspectj注释示例。不同之处在于,我想在JUnit TestClass上使用注释。我搜索了一段时间寻找解决方案,但没有找到正确的提示。

我的pom.xml的一部分

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.9.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.14.0</version>
    </dependency>
</dependencies>

<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.14.0</version>
        <configuration>
            <complianceLevel>1.8</complianceLevel>
            <!--<source>1.8</source>
            <target>1.8</target>-->
            <showWeaveInfo>true</showWeaveInfo>
            <verbose>true</verbose>
            <Xlint>ignore</Xlint>
            <!--<encoding>UTF-8 </encoding>-->
        </configuration>
        <executions>
            <execution>
                <phase>process-sources</phase>
                <goals>
                    <!-- use this goal to weave all your main classes -->
                    <goal>compile</goal>
                    <!-- use this goal to weave all your test classes -->
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>       
</plugins>

我的注解:

代码语言:javascript
复制
package com.mb.mtpp.main.extension.annotations;

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, ElementType.TYPE, ElementType.FIELD})
public @interface Secured {
public boolean isLocked() default false;
}

我的方面:

代码语言:javascript
复制
package com.mb.mtpp.main.extension.aspectj;

import com.mb.mtpp.main.extension.annotations.Secured;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public final class SecuredMethodAspect {

@Pointcut("@annotation(secured)")
    public void callAt(Secured secured) {
}

@Before("callAt(secured)")
public void around(JoinPoint pjp, Secured secured) throws Throwable {
    System.out.println("++++++++test++++++++");
    //return secured.isLocked() ? null : pjp.proceed();
}
}
代码语言:javascript
复制
@Secured(isLocked = true)
public class DummyClassTest {

@Test
@Secured(isLocked = true)
public void dummyTest4(){
    log.info("Test 4");
}
}

这个建议提到了类注释,我在日志中看到了它:

代码语言:javascript
复制
CLASSPATH component C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\plugins\maven\lib\maven3\boot\plexus-classworlds.license: java.util.zip.ZipException: error in opening zip file
[INFO] Join point 'staticinitialization(void com.mb.mtpp.main.dummy.DummyClassTest.<clinit>())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:23) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.dummy.DummyClassTest.dummyTest3())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:64) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.dummy.DummyClassTest.dummyTest4())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:71) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-call(void com.mb.mtpp.main.extension.DummyClass.function1())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:79) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-call(void com.mb.mtpp.main.extension.DummyClass.function2())' in Type 'com.mb.mtpp.main.dummy.DummyClassTest' (DummyClassTest.java:80) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.extension.DummyClass.function1())' in Type 'com.mb.mtpp.main.extension.DummyClass' (DummyClass.java:8) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)
[INFO] Join point 'method-execution(void com.mb.mtpp.main.extension.DummyClass.function2())' in Type 'com.mb.mtpp.main.extension.DummyClass' (DummyClass.java:13) advised by before advice from 'com.mb.mtpp.main.extension.aspectj.SecuredMethodAspect' (SecuredMethodAspect.java:62)

但是控制台中没有显示日志"++++++++test++++++++“。它在通知不存在的情况下执行。我对类、testcase和一个方法进行了注释,如示例中所示。我尝试了不同的设置我的切入点,但显示是最好的。然后这个班也会被建议。我不知道怎么回事。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-04 08:19:20

抱歉,我很忙。假设您的目录布局如下所示:

一些示例类可能如下所示:

代码语言:javascript
复制
package com.mb.mtpp.main.extension.annotations;

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, ElementType.TYPE, ElementType.FIELD })
public @interface Secured {
  boolean isLocked() default false;
}
代码语言:javascript
复制
package com.mb.mtpp.main.extension;

import com.mb.mtpp.main.extension.annotations.Secured;

public class MyClass {
  @Secured
  public void doSomething() {}
}
代码语言:javascript
复制
package com.mb.mtpp.main.extension.aspectj;

import com.mb.mtpp.main.extension.annotations.Secured;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public final class SecuredMethodAspect {
  @Pointcut("@annotation(secured) && execution(* *(..))")
  public void securedMethods(Secured secured) {}

  @Before("securedMethods(secured)")
  public void interceptSecuredMethods(JoinPoint joinPoint, Secured secured) {
    System.out.println(joinPoint);
  }
}
代码语言:javascript
复制
package com.mb.mtpp.main.extension;

import com.mb.mtpp.main.extension.annotations.Secured;
import org.junit.jupiter.api.Test;

@Secured(isLocked = true)
public class MyTest {
  @Test
  @Secured(isLocked = true)
  public void dummyTest4(){
    System.out.println("Test 4");
  }

  @Test
  @Secured(isLocked = true)
  public void dummyTest5(){
    System.out.println("Test 5");
    new MyClass().doSomething();
  }
}

你的POM是:

代码语言:javascript
复制
<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>org.example</groupId>
  <artifactId>SO_AJ_AspectNotTriggered_72344739</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.9.7</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.8.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M6</version>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.14.0</version>
        <configuration>
          <complianceLevel>1.8</complianceLevel>
          <showWeaveInfo>true</showWeaveInfo>
          <verbose>true</verbose>
          <Xlint>ignore</Xlint>
          <encoding>UTF-8</encoding>
        </configuration>
        <executions>
          <execution>
            <goals>
              <!--<goal>compile</goal>-->
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

然后,如果您运行mvn clean test或简单地将项目导入IntelliJ IDEA,则日志输出将是:

代码语言:javascript
复制
execution(void com.mb.mtpp.main.extension.MyTest.dummyTest4())
Test 4
execution(void com.mb.mtpp.main.extension.MyTest.dummyTest5())
Test 5

现在,如果出于任何原因,您也希望将方面应用于带注释的应用程序类,只需

and

  • uncomment <goal>compile</goal>.

  • 将方面从src/test/java移到src/main/java
  • <scope>test</scope>aspectjrt
  • 移除

那么控制台日志将是:

代码语言:javascript
复制
execution(void com.mb.mtpp.main.extension.MyTest.dummyTest4())
Test 4
execution(void com.mb.mtpp.main.extension.MyTest.dummyTest5())
Test 5
execution(void com.mb.mtpp.main.extension.MyClass.doSomething())

看见?在这种情况下,应用程序类MyClass也会被截获。

更新:关于为什么它不能在您自己的示例中工作的,这是因为您的POM的配置方式使得Maven Compiler插件重新编译了这些方面之后的AspectJ Maven插件。结果是,由于覆盖类文件,方面信息丢失了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72344739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档