如何使用Guice将必要的对象注入AspectJ方面

时间:2017-02-13 11:05:20

标签: java dependency-injection aop guice aspectj

有没有办法使用Guice和AspectJ的情况,我有一个方面,必须在其逻辑中使用一些复杂的实例化服务?

例如:

@Aspect
public class SomeAspect {

  private final ComplexServiceMangedByGuice complexServiceMangedByGuice;

  @Inject
  public SomeAspect(ComplexServiceMangedByGuice complexServiceMangedByGuice){
    this.complexServiceMangedByGuice = complexServiceMangedByGuice;
  }

  @AfterThrowing(value = "execution(* *(..))", throwing = "e")
  public void afterThrowingException(JoinPoint joinPoint, Throwable e){
    complexServiceMangedByGuice.doSomething(e);
  }
}

如果我尝试在示例中使用它(使用方面构造函数),则不会调用我的方面。如果我尝试注入字段(没有定义方面构造函数),将调用方面,但不会设置字段complexServiceMangedByGuice。 我发现的一个解决方案是在advice方法体中获取实例,因此一个方面看起来像这样:

@Aspect
public class SomeAspect {

private static ComplexServiceManagedByGuice complexServiceManagedByGuice;

  @AfterThrowing(value = "execution(* *(..))", throwing = "e")
  public void afterThrowingException(JoinPoint joinPoint, Throwable e){
    if(complexServiceManagedByGuice == null){
    Injector injector = Guice.createInjector(new ModuleWithComplexService());
    complexServiceMangedByGuice = injector.getInstance(ComlexServiceManagedByGuice.class);
    }
    complexServiceMangedByGuice.doSomething(e);
  }
}

但这有一些不良的开销。

2 个答案:

答案 0 :(得分:4)

您可以像这样注释方面类的字段:

@Inject
SomeDependency someDependency

然后让Guice通过在你的Guice模块的configure()方法中写下来将依赖关系注入到Aspect方面:

requestInjection(Aspects.aspectOf(SomeAspect.class));

requestInjection的文档说:

  

成功创建后,Injector将注入给定对象的实例字段和方法

来源:https://github.com/jponge/guice-aspectj-sample

答案 1 :(得分:1)

这是我一直在努力解决的问题,我认为没有一个好的答案。

这两个库基本上相互作用:AspectJ方面基本上是静态的,Guice abhors making anything injectable be static

我认为你的选择是:

  • 使用Guice AOP - 清洁,但与AspectJ相比有限(只能编织注入的类)
  • 将注射器放入静态"全球"参考,以便方面可以访问它。 (呸。)
  • 使用某种线程上下文(最终是一个线程局部的)来将注入器传达给方面(同样是yuck - 尽管可能更少)