Spring Dependency注入带注释的方面

时间:2009-08-27 21:55:11

标签: spring dependency-injection aop aspectj load-time-weaving

使用Spring我在注释的Aspect类上进行依赖注入时遇到了一些问题。 CacheService是在Spring上下文启动时注入的,但是当编织发生时,它表示cacheService为null。所以我不得不手动重新查看spring上下文并从那里获取bean。 还有另一种方法吗?

以下是我的方面的一个例子:

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import com.mzgubin.application.cache.CacheService;

@Aspect
public class CachingAdvice {

  private static Logger log = Logger.getLogger(CachingAdvice.class);

  private CacheService cacheService;

  @Around("execution(public *com.mzgubin.application.callMethod(..)) &&"
            + "args(params)")
    public Object addCachingToCreateXMLFromSite(ProceedingJoinPoint pjp, InterestingParams params) throws Throwable {
    log.debug("Weaving a method call to see if we should return something from the cache or create it from scratch by letting control flow move on");

    Object result = null;
    if (getCacheService().objectExists(params))}{
      result = getCacheService().getObject(params);
    } else {
      result = pjp.proceed(pjp.getArgs());
      getCacheService().storeObject(params, result);
    }
    return result;
  }

  public CacheService getCacheService(){
    return cacheService;
  }

  public void setCacheService(CacheService cacheService){
    this.cacheService = cacheService;
  }
}

3 个答案:

答案 0 :(得分:4)

由于方面是在Spring容器之前创建的,因此您必须从Aspect的工厂方法aspectOf(ExampleClass.class)中检索方面。

从Spring XML配置中,您可以像这样检索方面(对象):

<bean id="traceAspect" class="aspects.trace.TraceAspect"
    factory-method="aspectOf" />

工厂方法是检索在Spring容器外部创建的对象的常用方法,如Enum。

答案 1 :(得分:3)

正如我所理解的那样,问题是Spring正在为你创建这种类型的bean,但是AspectJ框架也在创建这种类型的实例化,因为它不知道Spring已经这样做了。

我相信你想给Spring一个工厂方法来实例化bean,这也让AspectJ知道了Aspect的创建:

<!-- An @Aspect-annotated class -->
<bean id="bar" class="com.foo.bar" factory-method="aspectOf">
    <property name="meaning" value="42" />
</bean>

为了给予应有的信任,我今天早些时候遇到了这个问题,然后在elsewhere之后找到答案,所以我回来关闭循环。

我对这里发生的魔法并不十分清楚,但我确实看到有一个Aspects类提供了一些这种风格的静态构造函数。据推测,AspectJ正在为每个方面编织同名的静态方法,以促进这种构造。

答案 2 :(得分:2)

我也遇到过这样的问题。

这是如何解决的:

@Aspect
public class MyAspect {
  @Resource // telling spring that at first look up bean by name;
  Session session; // resource that won't of being setup;

  private static class MyAspectHolder {
    static final MyAspect instance = new MyAspect();
  }

  ...

  // special purpose method w/o it - stuff doesnt work;
  public static MyAspect aspectOf() {
    return MyAspectHolder.instance;
  }
}

当然,不要忘记配置中的<aop:aspectj-autoproxy />以及方面bean定义。