Пролетна зависимост Инжектиране на анотиран аспект

Използвайки Spring, имах някои проблеми с извършването на инжектиране на зависимост на анотиран клас Aspect. CacheService се инжектира при стартиране на контекста на Spring, но когато се извърши тъкането, се казва, че cacheService е нула. Така че съм принуден да претърся контекста на пролетта ръчно и да взема зърната от там. Има ли друг начин да го направим?

Ето пример за моя аспект:

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, трябва да извлечете аспекта от фабричния метод на аспекта aspectOf(ExampleClass.class).

От XML конфигурацията на Spring можете да извлечете аспекта (обекта) по следния начин:

<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 singleton. - person PJH; 31.10.2013
comment
Ако пишете класически аспект на aspectj, статичният инструмент за достъп на aspecOf се генерира от компилатора на aspectj: - person Norbert Madarász; 21.04.2014