5

使用 Spring 我在对带注释的 Aspect 类进行依赖注入时遇到了一些问题。CacheService 是在 Spring 上下文启动时注入的,但是当编织发生时,它说 cacheService 为空。所以我不得不手动重新查找 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;
  }
}
4

3 回答 3

4

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

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

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

工厂方法是检索在 Spring 容器(如 Enum)之外创建的对象的常规方法。

于 2010-03-30T20:53:36.670 回答
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>

为了给予应有的荣誉,我今天早些时候遇到了这个问题,后来在其他地方找到了答案,所以我回来结束循环。

我对这里发生的魔法不是很清楚,但我确实看到有一个 Aspects 类提供了一些这种风格的静态构造函数。据推测,AspectJ 也将同名的静态方法编织到每个 Aspect 上以促进这种构造。

于 2009-09-24T22:37:39.723 回答
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 的定义。

于 2010-03-16T18:09:16.130 回答