结合 Guice 和 AOP
Incorporating Guice and AOP
我正在构建一个包,它试图根据标志拦截函数的 return 值。我的设计涉及一些 AOP。这个想法是 class FirstIntercept
拦截调用 firstCall
并将参数存储在 Parameters
对象中。然后,第二个 class SecondIntercept
拦截另一个调用 secondCall
并根据 Parameters
:
中填充的内容执行一些逻辑
// pseudoish code
public class FirstIntercept {
private Parameters param;
@AfterReturning(pointcut = "execution(* ...firstCall(..))", returning = "payload")
public void loadParam(Joinpoint joinPoint, Object payload) {
// logic handling payload returned from firstCall()
// logic provides a Boolean flag
this.param = new Parameters(flag);
}
}
public class Parameters {
@Getter
private Boolean flag;
public Parameters(Boolean flag) {
this.flag = flag;
}
}
public class SecondIntercept {
private static Parameters params;
@Around("execution(* ...secondCall(..))")
public void handleSecondCallIntercept(ProceedingJoinPoint joinPoint) {
// want to do logic here based on what params contains
}
}
我想实现的是在通过AOP调用FirstIntercept.loadParam
时,一次性加载Parameters
对象。我不太确定如何才能坚持下去。我在网上看了看 Google guice 似乎很有前途。我相信第一步是在 Parameters
上使用依赖注入,但我真的不确定。有人可以帮我指出正确的方向吗?
编辑:
所以我尝试了这个设置:
public class FirstIntercept implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("invoked!");
return invocation.proceed();
}
@AfterReturning(pointcut = "execution(* ...firstCall(..))", returning = "payload")
public void loadParam(Joinpoint joinPoint, Object payload) {
// do stuff
}
public String firstCall() {
return "hello";
}
}
public class InterceptionModule extends AbstractModule {
protected void configure() {
FirstIntercept first = new FirstIntercept();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AfterReturning.class), first);
}
}
public class FirstIterceptTest {
@Test
public void dummy() {
Injector injector = Guice.createInjector(new InterceptionModule());
FirstIntercept intercept = injector.getInstance(FirstIntercept.class);
intercept.firstCall();
}
}
当我执行 .firstCall()
时,我可以看到 @AfterReturning
运行 但未调用调用。
如果您扩展 AOP https://github.com/google/guice/wiki/AOP 的文档,您应该得到接近于:
的内容
public class FirstInterceptor implements MethodInterceptor {
@Inject Parameters parameters; // Injected with singleton Parameter
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = invocation.proceed();
// your logic based on result to set parameters.setFlag()
return result;
}
}
然后第二个:
public class SecondInterceptor implements MethodInterceptor {
@Inject Parameters parameters; // Injected with singleton Parameter
public Object invoke(MethodInvocation invocation) throws Throwable {
boolean flag = parameters.getFlag();
// your logic here
return invocation.proceed(); // maybe maybe not?
}
}
你的参数是关键,你需要确保它是线程安全的,这是另一个话题。但是要注入这些你需要:
public class InterceptionModule extends AbstractModule {
protected void configure() {
// Ensure there is only ever one Parameter injected
bind(Parameter.class).in(Scopes.SINGLETON);
// Now inject and bind the first interceptor
FirstInterceptor firstInterceptor = new FirstInterceptor();
requestInjection(firstInterceptor );
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AfterReturning.class),
firstInterceptor);
// Now inject and bind the second interceptor
SecondInterceptor SecondInterceptor = new SecondInterceptor ();
requestInjection(firstInterceptor);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AfterReturning.class),
SecondInterceptor);
}
}
编辑
看看你在做什么。
- 你告诉 Guice 用带有 FirstInterceptor 的 @AfterReturn 包装一个方法
- 然后你调用 interceptor.firstCall()
第一次调用没有@AfterReturn 注解,为什么要匹配那个配置?
我猜你是否打过电话:
intercept.loadParam();
您会看到调用方法。此外,这对于测试来说非常有用,但在现实生活中,您希望服务级别 class 具有 @AfterReturn,然后将其注入到另一个将调用 LoadParam 的 Api/Job/Etc 中。
编辑
不好了。看看这一行
bindInterceptor(Matchers.any(), // a class with this matcher
Matchers.annotatedWith(AfterReturning.class), // a method with this
firstInterceptor);
这意味着注入器仅在 loadParams 上触发。您需要使用@AfterReturning 注释您希望引起拦截的class 方法。并且您希望 loadParams 成为调用方法。
我正在构建一个包,它试图根据标志拦截函数的 return 值。我的设计涉及一些 AOP。这个想法是 class FirstIntercept
拦截调用 firstCall
并将参数存储在 Parameters
对象中。然后,第二个 class SecondIntercept
拦截另一个调用 secondCall
并根据 Parameters
:
// pseudoish code
public class FirstIntercept {
private Parameters param;
@AfterReturning(pointcut = "execution(* ...firstCall(..))", returning = "payload")
public void loadParam(Joinpoint joinPoint, Object payload) {
// logic handling payload returned from firstCall()
// logic provides a Boolean flag
this.param = new Parameters(flag);
}
}
public class Parameters {
@Getter
private Boolean flag;
public Parameters(Boolean flag) {
this.flag = flag;
}
}
public class SecondIntercept {
private static Parameters params;
@Around("execution(* ...secondCall(..))")
public void handleSecondCallIntercept(ProceedingJoinPoint joinPoint) {
// want to do logic here based on what params contains
}
}
我想实现的是在通过AOP调用FirstIntercept.loadParam
时,一次性加载Parameters
对象。我不太确定如何才能坚持下去。我在网上看了看 Google guice 似乎很有前途。我相信第一步是在 Parameters
上使用依赖注入,但我真的不确定。有人可以帮我指出正确的方向吗?
编辑:
所以我尝试了这个设置:
public class FirstIntercept implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("invoked!");
return invocation.proceed();
}
@AfterReturning(pointcut = "execution(* ...firstCall(..))", returning = "payload")
public void loadParam(Joinpoint joinPoint, Object payload) {
// do stuff
}
public String firstCall() {
return "hello";
}
}
public class InterceptionModule extends AbstractModule {
protected void configure() {
FirstIntercept first = new FirstIntercept();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AfterReturning.class), first);
}
}
public class FirstIterceptTest {
@Test
public void dummy() {
Injector injector = Guice.createInjector(new InterceptionModule());
FirstIntercept intercept = injector.getInstance(FirstIntercept.class);
intercept.firstCall();
}
}
当我执行 .firstCall()
时,我可以看到 @AfterReturning
运行 但未调用调用。
如果您扩展 AOP https://github.com/google/guice/wiki/AOP 的文档,您应该得到接近于:
的内容public class FirstInterceptor implements MethodInterceptor {
@Inject Parameters parameters; // Injected with singleton Parameter
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = invocation.proceed();
// your logic based on result to set parameters.setFlag()
return result;
}
}
然后第二个:
public class SecondInterceptor implements MethodInterceptor {
@Inject Parameters parameters; // Injected with singleton Parameter
public Object invoke(MethodInvocation invocation) throws Throwable {
boolean flag = parameters.getFlag();
// your logic here
return invocation.proceed(); // maybe maybe not?
}
}
你的参数是关键,你需要确保它是线程安全的,这是另一个话题。但是要注入这些你需要:
public class InterceptionModule extends AbstractModule {
protected void configure() {
// Ensure there is only ever one Parameter injected
bind(Parameter.class).in(Scopes.SINGLETON);
// Now inject and bind the first interceptor
FirstInterceptor firstInterceptor = new FirstInterceptor();
requestInjection(firstInterceptor );
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AfterReturning.class),
firstInterceptor);
// Now inject and bind the second interceptor
SecondInterceptor SecondInterceptor = new SecondInterceptor ();
requestInjection(firstInterceptor);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(AfterReturning.class),
SecondInterceptor);
}
}
编辑 看看你在做什么。
- 你告诉 Guice 用带有 FirstInterceptor 的 @AfterReturn 包装一个方法
- 然后你调用 interceptor.firstCall()
第一次调用没有@AfterReturn 注解,为什么要匹配那个配置?
我猜你是否打过电话:
intercept.loadParam();
您会看到调用方法。此外,这对于测试来说非常有用,但在现实生活中,您希望服务级别 class 具有 @AfterReturn,然后将其注入到另一个将调用 LoadParam 的 Api/Job/Etc 中。
编辑 不好了。看看这一行
bindInterceptor(Matchers.any(), // a class with this matcher
Matchers.annotatedWith(AfterReturning.class), // a method with this
firstInterceptor);
这意味着注入器仅在 loadParams 上触发。您需要使用@AfterReturning 注释您希望引起拦截的class 方法。并且您希望 loadParams 成为调用方法。