【问题标题】:Spring Dependency Injecting an annotated AspectSpring 依赖注入注解的切面
【发布时间】:2010-11-23 13:22:43
【问题描述】:

使用 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;
  }
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案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;
        }
      }
      

      当然不要忘记配置中的&lt;aop:aspectj-autoproxy /&gt; 以及方面 bean 定义。

      【讨论】:

      • 所以简单地在我的方面类中设置 aspectOf 方法似乎可以解决这个问题。不知道为什么这只是工作,因为我见过的大多数其他修复都没有。顺便说一句,通过 spring-aspects 和其他一些方法尝试了 @Configurable,但似乎没有一个将 bean 正确连接到 aspectj 单例。
      • 如果你写的是经典的aspectj aspect,aspecOf静态访问器是aspectj编译器生成的:
      【解决方案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 也在为每个 Aspect 编织同名的静态方法以促进这种构造。

      【讨论】:

        猜你喜欢
        • 2011-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-10
        • 1970-01-01
        • 2023-03-09
        • 2018-11-21
        • 2012-12-23
        相关资源
        最近更新 更多