根据我对您的other question 的回答,我将向您解释您可以做什么。一些提示:
您可以只使用around(),而不是before() 和after()。
您不应在单例方面为流程实例使用私有成员,因为如果您在多个线程中有异步流程,则该成员可能会被覆盖。因此,您的方法不是线程安全的,您应该改用局部变量。
您不应在after() 建议中打印“进程运行成功”,因为after() 也会在异常之后运行。因此,您不能安全地假设该过程成功运行,只能假设它完全运行。你应该写“完成的过程”或类似的。顺便说一句,如果您想区分成功的流程和以异常结束的此类流程,您可能需要查看切入点类型 after() returning 和 after() throwing()。
使用抽象基类而不直接在那里定义成员result 是没有意义的。如果您可以将其作为父类中的受保护成员,为什么要将其添加为每个子类中的私有成员?我们仍然在这里做 OOP(当然除了 AOP),对吧?优点是您可以使用基类直接从切面访问成员,就像您已经在切入点中所做的那样。
这是给你的MCVE:
进程类:
package de.scrum_master.app;
import java.io.IOException;
import java.util.Map;
public abstract class RunnableProcess {
protected String result = "foo";
public abstract void run(Map processContext) throws IOException;
}
package de.scrum_master.app;
import java.io.IOException;
import java.util.Map;
public class FirstRunnableProcess extends RunnableProcess {
@Override
public void run(Map processContext) throws IOException {
System.out.println("I am #1");
result = "first";
}
}
package de.scrum_master.app;
import java.io.IOException;
import java.util.Map;
public class SecondRunnableProcess extends RunnableProcess {
@Override
public void run(Map processContext) throws IOException {
System.out.println("I am #2");
result = "second";
}
}
驱动程序应用:
package de.scrum_master.app;
import java.io.IOException;
public class Application {
public static void main(String[] args) throws IOException {
new FirstRunnableProcess().run(null);
new SecondRunnableProcess().run(null);
}
}
方面:
在这里,您只需将target() 对象绑定到切入点中的一个参数,并在两个建议中使用它。
package de.scrum_master.aspect;
import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
import de.scrum_master.app.RunnableProcess;
import java.util.Map;
public privileged aspect ProcessRunInterceptorProtocol {
pointcut runProcess(RunnableProcess process) :
call(void RunnableProcess.run(Map)) && target(process);
before(RunnableProcess process): runProcess(process) {
Logger logger = getLogger(process.getClass());
logger.info("logger = " + logger);
logger.info("running process = " + thisJoinPoint);
}
after(RunnableProcess process): runProcess(process) {
Logger logger = getLogger(process.getClass());
logger.info("finished process = " + thisJoinPoint);
logger.info("result = " + process.result);
}
}
带有 JDK 日志记录的控制台日志(去除了一些噪音):
INFORMATION: logger = org.slf4j.impl.JDK14LoggerAdapter(de.scrum_master.app.FirstRunnableProcess)
INFORMATION: running process = call(void de.scrum_master.app.FirstRunnableProcess.run(Map))
I am #1
INFORMATION: finished process = call(void de.scrum_master.app.FirstRunnableProcess.run(Map))
INFORMATION: result = first
INFORMATION: logger = org.slf4j.impl.JDK14LoggerAdapter(de.scrum_master.app.SecondRunnableProcess)
INFORMATION: running process = call(void de.scrum_master.app.SecondRunnableProcess.run(Map))
I am #2
INFORMATION: finished process = call(void de.scrum_master.app.SecondRunnableProcess.run(Map))
INFORMATION: result = second