Spring Зависимость, внедряющая аннотированный аспект

Использование Spring У меня были некоторые проблемы с внедрением зависимостей в аннотированный класс Aspect. CacheService вводится при запуске контекста Spring, но когда происходит переплетение, он говорит, что cacheService имеет значение null. Поэтому я вынужден пересматривать контекст весны вручную и получать оттуда 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;
  }
}

person Community    schedule 27.08.2009    source источник


Ответы (3)


Поскольку аспект создается до контейнера Spring, вам необходимо получить аспект из фабричного метода Aspect аспектаOf(ExampleClass.class).

Из конфигурации Spring XML вы можете получить аспект (объект) следующим образом:

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

Фабричные методы — это обычный способ извлечения объектов, созданных вне контейнера Spring, таких как Enum.

person Espen    schedule 30.03.2010

Проблема, насколько я понимаю, заключается в том, что 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, чтобы облегчить такую ​​конструкцию.

person RonU    schedule 24.09.2009

Я тоже столкнулся с такой проблемой.

Вот как это было исправлено:

@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 /> в своей конфигурации вместе с определением компонента аспекта.

person artemv    schedule 16.03.2010
comment
поэтому простая установка метода aspectOf в моем классе аспектов, похоже, исправляет это. Не уверен, почему это просто работает, потому что большинство других исправлений, которые я видел, не работают. Кстати, попробовал @Configurable через spring-aspects и некоторые другие, но ни один из них, похоже, не смог правильно подключить bean-компонент к синглтону aspectj. - person PJH; 31.10.2013
comment
Если вы пишете классический аспект, то статический метод доступа aspecOf генерируется компилятором аспекта: - person Norbert Madarász; 21.04.2014