2012-04-18 10 views
5

Ho un progetto costituito da due sottoprogetti che sono entrambi progetti Spring e hanno un applicationContext.xml ciascuno.Spring Aspect non eseguito quando definito in altro JAR

Uno è un progetto framework (che termina come un JAR) e uno è l'applicazione effettiva (che finisce come WAR e dipende dal JAR e importa il file applicationContext.xml del JAR nel proprio applicationContext.xml).

Nel progetto quadro, ho definito un aspetto per tutti i metodi pubblici.

@Aspect 
@Configurable 
public class MyAspect { 

    @Autowired 
    private SomeBean mBean; 

    @Pointcut("execution(public * *(..))") 
    public void anyPublicMethod() { 
    } 

    @Before("anyPublicMethod()") 
    public void checkAuthorization(JoinPoint pJoinPoint) { 
     mBean.doSomething(); 
    } 
} 

E Ho attivato AOP nel applicationContext.xml del quadro (che viene importato dalla applicationContext.xml del progetto di applicazione effettiva).

... 
    <context:spring-configured /> 

    <context:component-scan base-package="com.mypackage" /> 

    <aop:aspectj-autoproxy/> 
... 

Durante il test nel progetto quadro, l'aspetto viene eseguito come previsto quando si richiamano metodi pubblici su bean Spring.

Come detto sopra, il progetto quadro è incluso nel progetto dell'applicazione come dipendenza ma l'aspetto non viene eseguito quando si chiamano i metodi di corrispondenza (qualsiasi pubblico) nel progetto dell'applicazione su qualsiasi bean Spring.

Ho anche provato a utilizzare la configurazione XML dell'aspetto. Ciò porta allo stesso comportamento.

risposta

4

IMHO, è possibile modificare leggermente l'approccio.

La prima cosa che vorrei fare è quello di delegare la configurazione del contesto applicativo per la guerra al web.xml:

<context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>WEB-INF/classes/spring*.xml</param-value> 
</context-param> 

In secondo luogo vorrei consentire AOP in voi contesto applicativo del file di guerra, in quanto questo è dove vuoi usarlo Sembra, al momento, come se si stesse importando il contesto dell'applicazione con la configurazione aop solo per averlo nel progetto web, il che forse è sbagliato.

Infine suppongo che questi siano aspetti di runtime e non compilati, in quest'ultimo caso è necessario ricompilare con aspectj nel progetto di guerra indipendentemente dalla dipendenza.

+0

Abilitare AOP nel contesto dell'applicazione non ha risolto il problema. – tobiasbayer

+0

Ho anche letto che l'autoproxying della molla si applica solo ai bean con gestione a molla, che non è configurabile. Prova a contrassegnarlo come componente per favore? Rif. - 7.2.2 Dichiarazione di un aspetto http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/aop.html – MikePatel

+0

Penso che tu stia confondendo l'applicazione di un aspetto con la sua definizione qui. La documentazione dice che un aspetto può essere __applied__ solo a un bean Spring. Questo non ha nulla a che fare con la dichiarazione dell'aspetto stesso. Deve funzionare anche usando '' @ Aspect'' (senza '' @ Configurable'' o '' @ Component''). Nel mio esempio, l'aspetto è '' @ Configurable'' oltre al campo '' @ Autowired'' per essere iniettato. – tobiasbayer

0

Questo è quello che faccio:

<context:annotation-config/> 
<context:component-scan base-package="my.pkg" scoped-proxy="interfaces"/> 
<aop:aspectj-autoproxy proxy-target-class="true" /> 

Anche se non posso dire se funzionerà nel tuo caso .... sarebbe d'aiuto se si imposta una versione ridotta del progetto presso github.

Questo non richiede alcun codice byte che intesse o strumenta il jvm. Assicurati di utilizzare gli attributi auto-iniettati quando chiami il metodo in questione, ad es.

@Autowired 
private MyType myTypeInstance; // MyType is usually an interface 

public void someMethod() { 
    // myTypeInstance is actually a proxy object... thereby providing the 
    // access point for the weaving stuff. (as far as I understand it) 
    myTypeInstance.method(); 
} 

caso contrario, seguire these instructions se non vi piacciono le deleghe di classe AOP primavera gestiti.

0

penso che è necessario per rendere il vostro aspetto di un componente di averlo riconosciuto entro la primavera:

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-at-aspectj

aspetti rilevato automaticamente attraverso la scansione componente

È possibile registrarsi classi aspetto come fagioli regolari nella configurazione XML di Spring, oppure rilevarli automaticamente tramite la scansione del percorso di classe, proprio come qualsiasi altro bean Spring-managed . Tuttavia, notare che l'annotazione @Aspect non è sufficiente per il rilevamento automatico nel classpath: A tale scopo, è necessario aggiungere un'annotazione @Component separata (o in alternativa un'annotazione stereotipo personalizzata che si qualifica, come da regole di Spring's scanner componente).

1

In Spring MVC webapps, in realtà esistono 2 contesti: il contesto di root e il contesto della servlet. Assicurati di configurare il tuo aspetto nel contesto servlet. In effetti, il contesto del servlet "vede" la radice uno - e non il contrario:

Nel framework MVC Web, ogni DispatcherServlet ha il suo WebApplicationContext, che eredita tutti i fagioli già definite nel radice WebApplicationContext. Questi bean ereditati possono essere sovrascritti nell'ambito specifico del servlet ed è possibile definire nuovi bean specifici dell'ambito in una determinata istanza Servlet.

Così il vostro importazione della configurazione del quadro deve essere fatta nel file [servlet-name]-servlet.xml piuttosto che nell'altro (s) se volete che i vostri aspetti da applicare ai suoi fagioli.

Problemi correlati