AspectJ建议不会在Maven多模块设置中触发
我正在尝试使用Aspectj进行AOP,但我不知道为什么不执行我的方面,它只运行主类。 这是我第一次这样做,所以我可能做错了什么。
这是我的代码:
方面:
@Aspect public class YourAspect { @Pointcut("@annotation(yourAnnotationVariableName)") public void annotationPointCutDefinition(YourAnnotation yourAnnotationVariableName){ } @Pointcut("execution(* *(..))") public void atExecution(){} @Around("annotationPointCutDefinition(yourAnnotationVariableName) && atExecution()") public Object aroundAdvice(ProceedingJoinPoint joinPoint, YourAnnotation yourAnnotationVariableName) throws Throwable { if(yourAnnotationVariableName.isRun()) { Object returnObject = null; try { System.out.println("aspects.YourAspect's aroundAdvice's body is now executed Before yourMethodAround is called."); returnObject = joinPoint.proceed(); } catch (Throwable throwable) { throw throwable; } finally { System.out.println("aspects.YourAspect's aroundAdvice's body is now executed After yourMethodAround is called."); } return returnObject; } return joinPoint.proceed(); } @After("annotationPointCutDefinition(yourAnnotationVariableName) && atExecution()") public void printNewLine(JoinPoint pointcut, YourAnnotation yourAnnotationVariableName){ System.out.print("End\n\r"); } }
注释:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface YourAnnotation { public boolean isRun() default true; }
主类:
public class MainClass{ public static void main(String[] args) { MainClass yourClass = new MainClass (); yourClass.yourMethodAround(); } @YourAnnotation public void yourMethodAround(){ System.out.println("Executing TestTarget.yourMethodAround()"); } }
我正在使用两个模块,POM看起来像这样:
Aspect的POM:
4.0.0 Group Aspects 1.0-SNAPSHOT org.codehaus.mojo aspectj-maven-plugin org.apache.maven.plugins maven-compiler-plugin org.aspectj aspectjweaver 1.8.10
主要POM:
4.0.0 Group Main 1.0-SNAPSHOT org.codehaus.mojo aspectj-maven-plugin 1.7 1.8 1.8 1.8 Group Aspects compile test-compile maven-assembly-plugin 2.5.5 false jar-with-dependencies aspects.MainClass a-make-assembly package single org.codehaus.mojo exec-maven-plugin 1.2.1 aspects.MainClass Group Aspects 1.0-SNAPSHOT
我在两个项目中都进行了mvn clean install,然后在Main项目中执行了mvn exec:java,它只运行方法,而不是方面。 谁能帮我?
谢谢!
这是一个多模块解决方案。
主POM(所有其他人的父母):
这里我们定义所有具有基本配置的插件(更具体的配置可以在“应用程序”模块中找到)并管理所有依赖版本。
4.0.0 de.scrum-master.stackoverflow main 1.0-SNAPSHOT pom UTF-8 1.8 1.8.10 org.apache.maven.plugins maven-compiler-plugin 3.6.1 ${java.source-target.version} ${java.source-target.version} false org.codehaus.mojo aspectj-maven-plugin 1.10 ${java.source-target.version} ${java.source-target.version} ignore ${java.source-target.version} ${project.build.sourceEncoding} process-sources compile test-compile org.aspectj aspectjtools ${aspectj.version} org.aspectj aspectjweaver ${aspectj.version} org.apache.maven.plugins maven-assembly-plugin 2.5.5 false jar-with-dependencies a-make-assembly package single org.codehaus.mojo exec-maven-plugin 1.5.0 org.aspectj aspectjrt ${aspectj.version} de.scrum-master.stackoverflow common 1.0-SNAPSHOT de.scrum-master.stackoverflow aspect 1.0-SNAPSHOT common application aspect
模块“常见”:
该模块包含“应用程序”和“方面”使用的代码,更具体地说,在注释类的情况下。
4.0.0 de.scrum-master.stackoverflow main 1.0-SNAPSHOT common
package de.scrum_master.common; 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 YourAnnotation { boolean isRun() default true; }
模块“方面”:
这里我们只有方面代码。
4.0.0 de.scrum-master.stackoverflow main 1.0-SNAPSHOT aspect org.codehaus.mojo aspectj-maven-plugin org.aspectj aspectjrt de.scrum-master.stackoverflow common
package de.scrum_master.aspect; import de.scrum_master.common.YourAnnotation; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; @Aspect public class YourAspect { @Pointcut("@annotation(yourAnnotationVariableName)") public void annotationPointCutDefinition(YourAnnotation yourAnnotationVariableName) { } @Pointcut("execution(* *(..))") public void atExecution() { } @Around("annotationPointCutDefinition(yourAnnotationVariableName) && atExecution()") public Object aroundAdvice(ProceedingJoinPoint thisJoinPoint, YourAnnotation yourAnnotationVariableName) throws Throwable { if (yourAnnotationVariableName.isRun()) { Object result; try { System.out.println("Before " + thisJoinPoint); result = thisJoinPoint.proceed(); } catch (Throwable t) { throw t; } finally { System.out.println("After " + thisJoinPoint); } return result; } return thisJoinPoint.proceed(); } }
模块“申请”:
该模块包含应用程序代码。 它配置了Exec Maven和Maven Assembly插件。 此外,将“aspect”模块定义为AspectJ Maven的方面库。
4.0.0 de.scrum-master.stackoverflow main 1.0-SNAPSHOT application org.apache.maven.plugins maven-assembly-plugin true de.scrum_master.app.MainClass org.codehaus.mojo exec-maven-plugin de.scrum_master.app.MainClass org.codehaus.mojo aspectj-maven-plugin de.scrum-master.stackoverflow aspect de.scrum-master.stackoverflow common de.scrum-master.stackoverflow aspect org.aspectj aspectjrt
package de.scrum_master.app; import de.scrum_master.common.YourAnnotation; public class MainClass { public static void main(String[] args) { MainClass yourClass = new MainClass(); yourClass.yourMethodAround(); } @YourAnnotation public void yourMethodAround() { System.out.println("Executing TestTarget.yourMethodAround()"); } }
构建日志:
Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem $ mvn clean install (...) [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] main ............................................... SUCCESS [ 0.241 s] [INFO] common ............................................. SUCCESS [ 0.970 s] [INFO] aspect ............................................. SUCCESS [ 1.058 s] [INFO] application ........................................ SUCCESS [ 0.607 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.111 s [INFO] Finished at: 2017-04-07T17:15:39+02:00 [INFO] Final Memory: 23M/378M [INFO] ------------------------------------------------------------------------
运行日志:
Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem $ cd application/ Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem/application $ mvn exec:java (...) [INFO] ------------------------------------------------------------------------ [INFO] Building application 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- exec-maven-plugin:1.5.0:java (default-cli) @ application --- Before execution(void de.scrum_master.app.MainClass.yourMethodAround()) Executing TestTarget.yourMethodAround() After execution(void de.scrum_master.app.MainClass.yourMethodAround()) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ (...) Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem/application $ java -jar target/application-1.0-SNAPSHOT.jar Before execution(void de.scrum_master.app.MainClass.yourMethodAround()) Executing TestTarget.yourMethodAround() After execution(void de.scrum_master.app.MainClass.yourMethodAround())
更新:我将整个示例项目推送到GitHub存储库 。
好的,你去吧。 我没有在不同的项目/包中拆分东西以保持尽可能简单。
项目pom.xml:
4.0.0 Group Main 1.0-SNAPSHOT org.aspectj aspectjweaver 1.8.10 org.codehaus.mojo aspectj-maven-plugin 1.7 1.8 1.8 1.8 compile maven-assembly-plugin true yourpackage.AspectJRawTest jar-with-dependencies package single
注释(你正确地写了这个):
package yourpackage; 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 MyCustomAnnotation { public boolean isRun() default true; }
将在注释方法之前运行的自定义建议。 我不确定这个,术语对我来说并不是绝对清楚……但似乎工作:)
package yourpackage; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class MyCustomAspect { @Before("execution(* *.*(..)) && @annotation(MyCustomAnnotation)") public void advice(JoinPoint joinPoint) { System.out.printf("BINGO! advice() called before '%s'%n", joinPoint); } }
最后,主要类:
package yourpackage; public class AspectJRawTest { public static void main(String[] args) { System.out.println("custom annotation playground"); ISomething something = new SomethingImpl(); something.annotatedMethod(); something.notAnnotatedMethod(); } } interface ISomething { void annotatedMethod(); void notAnnotatedMethod(); } class SomethingImpl implements ISomething { @MyCustomAnnotation public void annotatedMethod() { System.out.println("I am annotated and something must be printed by an advice above."); } public void notAnnotatedMethod() { System.out.println("I am not annotated and I will not get any special treatment."); } }
我用这样的maven构建它: mvn clean compile assembly:single
创建一个包含依赖项的可执行jar。 然后,执行:
java -jar target/Main-1.0-SNAPSHOT-jar-with-dependencies.jar custom annotation playground BINGO! advice() called before 'execution(void yourpackage.SomethingImpl.annotatedMethod())' I am annotated and something must be printed by an advice above. I am not annotated and I will not get any special treatment.
我稍后会在某个地方上传一个完整的项目,并为您提供一个链接 ,但我发布的内容应该足够了。
我在IDEA中对此进行了测试,我无法对其进行配置以便为我做正确的编织(命名任何其他IDE,您将得到同样的问题)。 但我现在没时间做这件事,你必须自己处理这个任务。 好消息,它必须是可能的,因为一切都与裸骨maven一起工作。