2009-08-27 17 views
5

Uso di Spring Ho riscontrato alcuni problemi con l'esecuzione di un'iniezione di dipendenza su una classe Aspect con annotazioni. CacheService viene iniettato all'avvio del contesto Spring, ma quando avviene la tessitura, indica che cacheService è null. Quindi sono costretto a ricominciare manualmente il contesto di primavera e ottenere il bean da lì. C'è un altro modo per farlo?Dipendenza di primavera Iniezione di un Aspetto annotato

Ecco un esempio del mio aspetto:

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

risposta

3

Il problema, se ho capito bene, è che la primavera sta creando un fagiolo di questo tipo per voi, ma il quadro AspectJ sta anche creando un'istanza di questo tipo perché non sa che Spring lo ha fatto.

credo si vuole dare primavera una fabbrica-metodo da utilizzare per creare un'istanza di fagiolo che permette anche di AspectJ sapere viene creata l'Aspect:

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

Per dare il giusto merito, mi sono imbattuto in questa domanda prima di oggi e dopo ho trovato una risposta elsewhere, quindi sto tornando per chiudere il ciclo.

Non sono chiaro sull'accaduto magico qui, ma vedo che esiste una classe Aspects che fornisce alcuni costruttori statici di questo sapore. Presumibilmente AspectJ sta tessendo metodi statici con lo stesso nome su ogni Aspect e per facilitare questo tipo di costruzione.

2

Ho anche affrontato tale problema.

Ecco come è stato risolto:

@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; 
    } 
} 

E naturalmente non dimenticare <aop:aspectj-autoproxy /> nella configurazione insieme con la definizione aspetto di fagioli.

+0

così semplicemente l'impostazione del metodo aspectOf nella mia classe aspetto sembra risolvere questo problema. Non sono sicuro del perché funzioni semplicemente perché la maggior parte delle altre correzioni che ho visto non hanno funzionato. BTW ha provato @Configurable tramite gli aspetti di primavera e alcuni altri, ma nessuno sembrava collegare correttamente il bean all'aspetto singleton. – PJH

+0

Se si scrive il classico aspetto aspetto, l'accessore statico aspecOf viene generato dal compilatore aspectj: –

4

Poiché l'aspetto viene creato prima del contenitore Spring, è necessario recuperare l'aspetto dal metodo di fabbrica Aspectoff (ExampleClass.class).

Dalla configurazione XML Primavera, è possibile recuperare l'aspetto (oggetto) in questo modo:

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

metodi di fabbrica sono il modo normale per recuperare gli oggetti creati al di fuori del contenitore di primavera come un Enum.

Problemi correlati