2013-11-01 13 views
5

Ich habe eine einzelne WAR-App, die Spring verwendet und ihren Kontext auf zwei verschiedene Arten initialisiert. Es verwendet sowohl Annotation Config als auch XML Config. Also meine erste Frage ist:Ist es eine schlechte Idee, sowohl XML als auch Annotation Config in einem einzigen Projekt mit Spring zu verwenden?

Ist das immer eine schlechte Praxis und zu welchen Problemen kann es führen?

Zweitens verwendet es sowohl Annotationen als auch XML, da es seine REST-Controller mit Annotationen und seinen Services/DAOs mit XML einrichtet.

Jetzt habe ich einen Ratschlag, der gut auf den Diensten funktioniert, aber überhaupt nicht feuert, wenn auf den REST-Controllern verwendet.

Dies ist ein relevanter Teil davon:

@Aspect 
public class SessionAwareAspect { 

    private SessionManager sessionManager; 

    private EngineActionResolver actionResolver; 

    @Around("@annotation(sessionAware)") 
    public Object authenticate(final ProceedingJoinPoint invocation, SessionAware sessionAware) { 

     // some logic 
    } 

    @Required 
    public void setSessionManager(SessionManager sessionManager) { 
     this.sessionManager = sessionManager; 
    } 

    @Required 
    public void setActionResolver(EngineActionResolver actionResolver) { 
     this.actionResolver = actionResolver; 
    } 
} 

Es ist im Kontext wie so initialisiert wird:

<bean id="sessionAwareAspect" class="cayetano.pplive.core.session.SessionAwareAspect"> 
    <property name="sessionManager" ref="sessionManager"/> 
    <property name="actionResolver" ref="engineActionResolver" /> 
</bean> 

<aop:aspectj-autoproxy> 
    <aop:include name="sessionAwareAspect" /> 
</aop:aspectj-autoproxy> 

So ist meine zweite Frage lautet:

Ist die Tatsache, dass die Kontext ist sowohl mit Anmerkungen und XML der Grund, warum der Aspekt nicht auf die Controller ausgelöst wird initialisiert Wenn ja, wie kann ich es funktionieren lassen?

Danke,


Einige zusätzliche Informationen von den Bereitstellungsprotokollen.

Dies ist, wie die XML-Bohnen instanziiert erhalten:

Nov 01, 2013 1:02:09 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 
[list of DAOs/Services] 

.... irrelevant log 
.... 50/100 lines after 

Nov 01, 2013 1:02:22 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 
Nov 01, 2013 1:02:22 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 
[list of REST controllers] 

Also, wenn dies tatsächlich schafft 2 getrennte Bohnen Kontexte (oder?), Könnte es der Fall sein, dass der Aspekt überhaupt nicht existiert in der mit der Annotation initialisierte Kontext?

Thanks again,

+3

Es spielt keine Rolle, wie viele verschiedene Konfigurationsmöglichkeiten Sie verwenden, solange alles in einem einzigen ApplicationContext geladen ist, können Sie xml/annotations/java/properties perfekt anpassen (ja, Sie können sogar Eigenschaften verwenden, um einen Anwendungskontext zu erstellen)). Meine Vermutung ist der Grund, warum es nicht funktioniert, wenn der Aspekt von einem anderen Kontext geladen wird (wahrscheinlich 'ContextLoaderListener'), dann funktionieren Ihre Controller (wahrscheinlich' DispatcherServlet') und 'Bean (Factory) PostProcessor' nur in dem Kontext, in dem sie definiert sind in (was benötigt wird, um den Aspekt anzuwenden). –

+0

@ M.Deinum Ihr Kommentar sieht aus wie eine Antwort auf mich, Sie könnten es posten. – Simeon

+1

Ich denke, es muss eine Mischung sein. Wie sonst können Sie die Konfiguration hinzufügen, um nach Annotationen ohne XML zu suchen? Sie benötigen ein Minimum an XML, soweit ich weiß. – duffymo

Antwort

5

Welche Möglichkeiten der Konfiguration Sie verwendet keine Rolle, können Sie Anmerkungen/Java mischen und/XML Spiel und sogar Eigenschaften Dateien Bean-Konfiguration zum Ausdruck bringen. Wie du diese mixst/matchest ist egal.

Eine Sache im Auge zu behalten ist, dass Bean(Factory)PostProcessors nur im gleichenApplicationContext auf Bohnen arbeiten, wie sie in definiert sind. <aop:aspectj-autoproxy > registriert eine BeanPostProcessor die Proxies und wendet die Ratschläge (Aspekte) zu Bohnen erzeugt. Wenn dies in dem Kontext definiert ist, der von ContextLoaderListener geladen wird, wird nichts für Beans getan, die in dem Kontext sind, der durch den DispatcherServlet geladen wird.

Fügen Sie einfach den Aspekt und <aop:aspectj-autoproxy > zu beiden Konfigurationen hinzu und Ihre Aspekte sollten funktionieren. Falls nicht, müssen Sie möglicherweise die Erstellung klassenbasierter Proxies erzwingen (<aop:aspectj-autoproxy proxy-target-class="true">). Dies ist der Fall, wenn Ihre Klassen keine Schnittstelle implementieren (oder nur Markierungsschnittstellen wie Serializable).

1

Es stellte sich heraus, dass das Problem tatsächlich zwei separate Kontexte in der web.xml explizit definiert, die ich nicht kannte. Man vermisste einfach den Aspekt.

Soweit ich bisher gelesen habe, ist es nicht schlecht, Annotation-basierte und XML-basierte Konfiguration zu verwenden (abgesehen von der Tatsache, dass es ein bisschen inkonsistent ist). Es ist sogar recommended in some cases.