2 回答

TA貢獻1828條經驗 獲得超3個贊
我一發布這個,我就嘗試用以下命令更改 ReviewTask 和 AnnotationTask
@Override
public Object task( ProceedingJoinPoint proceedingJoinPoint, JobContext context ) throws Throwable {
log.info( "ReviewTask's task" );
/*
* do some validation if annotation is completed or not
*/
log.info( "not completing the review task due to some reason" );
context.setReviewTaskStatus( TaskStatus.IN_PROGRESS );
return proceedingJoinPoint.proceed();
}
這解決了我的問題。

TA貢獻1752條經驗 獲得超4個贊
你是對的,我剛剛注意到 TaskAspects 根本沒有被觸發。我沒有看到來自 TaskAspects 的任何日志。我可以在沒有任何 spring-aop 的情況下在 spring-boot 中使用 AspectJ 嗎?感謝您的查看并通知。非常贊賞。
基本上,您只需從要通過 AspectJ 使用的方面中刪除@Component注釋,并將這些方面添加到文件src/main/resources/org/aspectj/aop.xml(假設您使用 Maven 來構建項目):
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
? <weaver options="-verbose -showWeaveInfo">
? ? <!-- only weave classes in our application-specific packages -->
? ? <include within="com.spring.aspect.dynamicflow..*"/>
? </weaver>
? <aspects>
? ? <aspect name="com.spring.aspect.dynamicflow.aspect.TaskAspects"/>
? ? <aspect name="com.spring.aspect.dynamicflow.activity.AnnotationTask"/>
? ? <aspect name="com.spring.aspect.dynamicflow.activity.ReviewTask"/>
? </aspects>
</aspectj>
然后你開始你的應用程序-javaagent:/path/to/aspectjweaver.jar
,例如:
-javaagent:"c:\Users\me\.m2\repository\org\aspectj\aspectjweaver\1.9.4\aspectjweaver-1.9.4.jar"
您還可以在 Java 命令行上同時使用 AspectJ Weaver 和 Spring Instrument 這兩個代理,例如
-javaagent:"c:\Users\me\.m2\repository\org\aspectj\aspectjweaver\1.9.4\aspectjweaver-1.9.4.jar"?-javaagent:"c:\Program?Files\Java\spring-framework-5.1.9.RELEASE\libs\spring-instrument-5.1.9.RELEASE.jar"
為了您的方便,并且為了自己擁有一個示例項目,我在GitHub 存儲庫中共享了我的工作示例。有一個Spring AOP 分支和另一個AspectJ LTW 分支。這些分支之間的差異如下所示:
diff --git a/src/main/java/com/spring/aspect/dynamicflow/Application.java b/src/main/java/com/spring/aspect/dynamicflow/Application.java
index 2a7021e..3a7636f 100644
--- a/src/main/java/com/spring/aspect/dynamicflow/Application.java
+++ b/src/main/java/com/spring/aspect/dynamicflow/Application.java
@@ -8,6 +8,16 @@ import org.springframework.boot.SpringApplication;
?import org.springframework.boot.autoconfigure.SpringBootApplication;
?import org.springframework.context.ConfigurableApplicationContext;
?
+/**
+ * Run this from your IDE with
+ *
+ * a) either just -javaagent:/path/to/aspectjweaver.jar and without @EnableLoadTimeWeaving
+ *
+ * b) or with both -javaagent:/path/to/aspectjweaver.jar -javaagent:/path/to/spring-instrument.jar,
+ * either with or without @EnableLoadTimeWeaving. What benefit this has, I don't know.
+ *
+ * See also my extensive comment in Application class.
+ */
?@SpringBootApplication
?public class Application {
? ?private static final Logger log = LoggerFactory.getLogger(Application.class);
diff --git a/src/main/java/com/spring/aspect/dynamicflow/ApplicationConfig.java b/src/main/java/com/spring/aspect/dynamicflow/ApplicationConfig.java
index b4698e1..649a6ca 100644
--- a/src/main/java/com/spring/aspect/dynamicflow/ApplicationConfig.java
+++ b/src/main/java/com/spring/aspect/dynamicflow/ApplicationConfig.java
@@ -3,8 +3,34 @@ package com.spring.aspect.dynamicflow;
?import org.springframework.context.annotation.ComponentScan;
?import org.springframework.context.annotation.Configuration;
?import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.context.annotation.EnableLoadTimeWeaving;
?
+import static org.springframework.context.annotation.EnableLoadTimeWeaving.AspectJWeaving.ENABLED;
+
+/**
+ * Remarks about AspectJ load-time weaving(LTW) in Spring:
+ *
+ * According to the Spring manual it should be enough to put spring-instrument.jar is on the JVM command line
+ * in combination with @EnableLoadTimeWeaving. Actually this does help Spring detect the AspectJ weaver,
+ * I can see the aspects loaded. But obviously this happens too late after the application classes are
+ * already loaded, so the aspects do not have any effect. I even added a static block
+ * static { logger.info("JobProcessImpl class was loaded"); } to JobProcessImpl in order to check it an
+ * the log output occurs right before the aspects are being activated, which of course is too late.
+ *
+ * LTW works if
+ *
+ * a) either I have both Java agents aspectjweaver.jar and spring-instrument.jar on JVM command line
+ * in combination with @EnableLoadTimeWeaving (but then it tries to weave twice, I can see errors in the log)
+ * or without @EnableLoadTimeWeaving (no errors in the log)
+ *
+ * b) or if I only use aspectjweaver.jar without @EnableLoadTimeWeaving.
+ *
+ * The latter is no surprise because AspectJ is independent of Spring and of course works even if Spring is
+ * unaware of its presence. But if I want to advertise its presence via @EnableLoadTimeWeaving, I do not
+ * understand why spring-instrument.jar is not enough, as described in the Spring manual.
+ */
?@Configuration
?@EnableAspectJAutoProxy
?@ComponentScan("com.spring.aspect.dynamicflow")
+//@EnableLoadTimeWeaving(aspectjWeaving = ENABLED)
?public class ApplicationConfig {}
diff --git a/src/main/java/com/spring/aspect/dynamicflow/activity/AnnotationTask.java b/src/main/java/com/spring/aspect/dynamicflow/activity/AnnotationTask.java
index 3c6d5c4..bbdd5b1 100644
--- a/src/main/java/com/spring/aspect/dynamicflow/activity/AnnotationTask.java
+++ b/src/main/java/com/spring/aspect/dynamicflow/activity/AnnotationTask.java
@@ -6,9 +6,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
?import org.aspectj.lang.annotation.Aspect;
?import org.slf4j.Logger;
?import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
?
-@Component
?@Aspect
?public class AnnotationTask extends Task {
? ?private static final Logger log = LoggerFactory.getLogger(AnnotationTask.class);
diff --git a/src/main/java/com/spring/aspect/dynamicflow/activity/ReviewTask.java b/src/main/java/com/spring/aspect/dynamicflow/activity/ReviewTask.java
index ece0ff6..f364da2 100644
--- a/src/main/java/com/spring/aspect/dynamicflow/activity/ReviewTask.java
+++ b/src/main/java/com/spring/aspect/dynamicflow/activity/ReviewTask.java
@@ -6,9 +6,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
?import org.aspectj.lang.annotation.Aspect;
?import org.slf4j.Logger;
?import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
?
-@Component
?@Aspect
?public class ReviewTask extends Task {
? ?private static final Logger log = LoggerFactory.getLogger(ReviewTask.class);
diff --git a/src/main/java/com/spring/aspect/dynamicflow/activity/Task.java b/src/main/java/com/spring/aspect/dynamicflow/activity/Task.java
index 3f1f9ce..93b3b73 100644
--- a/src/main/java/com/spring/aspect/dynamicflow/activity/Task.java
+++ b/src/main/java/com/spring/aspect/dynamicflow/activity/Task.java
@@ -6,9 +6,7 @@ import org.aspectj.lang.annotation.Around;
?import org.aspectj.lang.annotation.Aspect;
?import org.slf4j.Logger;
?import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
?
-@Component
?@Aspect
?public abstract class Task {
? ?private static final Logger log = LoggerFactory.getLogger(Task.class);
diff --git a/src/main/java/com/spring/aspect/dynamicflow/aspect/TaskAspects.java b/src/main/java/com/spring/aspect/dynamicflow/aspect/TaskAspects.java
index 3bff7b5..a09d9d6 100644
--- a/src/main/java/com/spring/aspect/dynamicflow/aspect/TaskAspects.java
+++ b/src/main/java/com/spring/aspect/dynamicflow/aspect/TaskAspects.java
@@ -5,9 +5,7 @@ import org.aspectj.lang.annotation.Around;
?import org.aspectj.lang.annotation.Aspect;
?import org.slf4j.Logger;
?import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
?
-@Component
?@Aspect
?public class TaskAspects {
? ?private static final Logger log = LoggerFactory.getLogger(TaskAspects.class);
diff --git a/src/main/resources/org/aspectj/aop.xml b/src/main/resources/org/aspectj/aop.xml
new file mode 100644
index 0000000..56342b4
--- /dev/null
+++ b/src/main/resources/org/aspectj/aop.xml
@@ -0,0 +1,15 @@
+<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
+<aspectj>
+
+? <weaver options="-verbose -showWeaveInfo">
+? ? <!-- only weave classes in our application-specific packages -->
+? ? <include within="com.spring.aspect.dynamicflow..*"/>
+? </weaver>
+
+? <aspects>
+? ? <aspect name="com.spring.aspect.dynamicflow.aspect.TaskAspects"/>
+? ? <aspect name="com.spring.aspect.dynamicflow.activity.AnnotationTask"/>
+? ? <aspect name="com.spring.aspect.dynamicflow.activity.ReviewTask"/>
+? </aspects>
+
+</aspectj>
Task順便說一句,我也很快嘗試獲得 Spring AOP 方面(子類)和 AspectJ 方面的組合( TaskAspects,真是一個可怕的名字,為什么不TasksAspect或TaskInterceptor?)。盡管 Spring 手冊和郵件列表上的許多用戶都說,即使沒有額外的配置,也很容易結合這兩種方法,但我無法讓它按照我想要的方式運行。所以目前我還沒有解決方案。也許我只是犯了一個小錯誤。我是一名 AspectJ 專家,但實際上從未使用過 Spring 或 Spring AOP,抱歉。
更新:我忘了提及,在我的存儲庫中我還解決了我之前在評論中提到的這個問題:
如果你真的使用 AspectJ LTW 場景,你的 TaskAspects 方面會被頻繁觸發,因為within(com.spring.aspect.dynamicflow.activity.Task+)在 AspectJ 中不僅攔截方法執行,還攔截對象和類初始化、字段訪問、對其他類的方法調用等。所以要么你使用 AspectJ LTW,它也會打印很多或(...)
如果您使用該切入點,這確實是正確的。日志輸出(時間戳、日志通道信息等,從日志輸出中切斷)將是:
Handling the task aspects.
? staticinitialization(com.spring.aspect.dynamicflow.activity.Task.<clinit>)
Handling the task aspects.
? call(Logger org.slf4j.LoggerFactory.getLogger(Class))
Handling the task aspects.
? set(Logger com.spring.aspect.dynamicflow.activity.Task.log)
Handling the task aspects.
? staticinitialization(com.spring.aspect.dynamicflow.activity.AnnotationTask.<clinit>)
Handling the task aspects.
? call(Logger org.slf4j.LoggerFactory.getLogger(Class))
Handling the task aspects.
? set(Logger com.spring.aspect.dynamicflow.activity.AnnotationTask.log)
Handling the task aspects.
? execution(com.spring.aspect.dynamicflow.activity.Task())
Handling the task aspects.
? execution(com.spring.aspect.dynamicflow.activity.AnnotationTask())
Handling the task aspects.
? execution(Object com.spring.aspect.dynamicflow.activity.AnnotationTask.task(ProceedingJoinPoint, JobContext))
Handling the task aspects.
? get(Logger com.spring.aspect.dynamicflow.activity.AnnotationTask.log)
Handling the task aspects.
? call(void org.slf4j.Logger.info(String))
AnnotationTask's task
Handling the task aspects.
? get(Logger com.spring.aspect.dynamicflow.activity.AnnotationTask.log)
Handling the task aspects.
? call(void org.slf4j.Logger.info(String))
? Setting that the annotation is done.
Handling the task aspects.
? get(TaskStatus com.spring.aspect.dynamicflow.entity.TaskStatus.COMPLETED)
Handling the task aspects.
? call(void com.spring.aspect.dynamicflow.entity.JobContext.setAnnotationTaskStatus(TaskStatus))
Handling the task aspects.
? call(Object org.aspectj.lang.ProceedingJoinPoint.proceed())
Handling the task aspects.
? staticinitialization(com.spring.aspect.dynamicflow.activity.ReviewTask.<clinit>)
Handling the task aspects.
? call(Logger org.slf4j.LoggerFactory.getLogger(Class))
Handling the task aspects.
? set(Logger com.spring.aspect.dynamicflow.activity.ReviewTask.log)
Handling the task aspects.
? execution(com.spring.aspect.dynamicflow.activity.Task())
Handling the task aspects.
? execution(com.spring.aspect.dynamicflow.activity.ReviewTask())
Handling the task aspects.
? execution(Object com.spring.aspect.dynamicflow.activity.ReviewTask.task(ProceedingJoinPoint, JobContext))
Handling the task aspects.
? get(Logger com.spring.aspect.dynamicflow.activity.ReviewTask.log)
Handling the task aspects.
? call(void org.slf4j.Logger.info(String))
ReviewTask's task
Handling the task aspects.
? get(Logger com.spring.aspect.dynamicflow.activity.ReviewTask.log)
Handling the task aspects.
? call(void org.slf4j.Logger.info(String))
? Setting that the review is done.
Handling the task aspects.
? get(TaskStatus com.spring.aspect.dynamicflow.entity.TaskStatus.IN_PROGRESS)
Handling the task aspects.
? call(void com.spring.aspect.dynamicflow.entity.JobContext.setReviewTaskStatus(TaskStatus))
Handling the task aspects.
? call(Object org.aspectj.lang.ProceedingJoinPoint.proceed())
Processing the job with jobid 11
我還從日志行之間刪除了 AspectJ weaver 日志消息(其中一些是錯誤)。within(com.spring.aspect.dynamicflow.activity.Task+) && execution(* task(..))您會看到 29x“處理任務方面”,而不是僅 2x,這就是我為您更改切入點的原因?,F在日志輸出看起來符合預期:
Handling the task aspects.
? execution(Object com.spring.aspect.dynamicflow.activity.AnnotationTask.task(ProceedingJoinPoint, JobContext))
AnnotationTask's task
? Setting that the annotation is done.
Handling the task aspects.
? execution(Object com.spring.aspect.dynamicflow.activity.ReviewTask.task(ProceedingJoinPoint, JobContext))
ReviewTask's task
? Setting that the review is done.
Processing the job with jobid 11
添加回答
舉報