2011-12-16 10 views
15

Tengo una aplicación web de primavera con dos contextos: uno (applicationContext) construidas por ContextLoaderListener y un segundo (webContext) construidas por DispatcherServlet.Cómo tender un puente sobre eventos contexto de aplicación de primavera a otro contexto

Dentro del applicationContext hay un bean (org.springframework.security.authentication.DefaultAuthenticationEventPublisher) que dispara eventos de contexto de primavera.

Pero el receptor para el evento se define en el webContext. Y ese receptor no entendió el evento. (Si puse el receptor para fines de prueba en el applicationContext, entonces recibe el evento, pero no puedo hacerlo, porque necesito el webContext para su funcionalidad.)

Así que mi pregunta es cómo salvar los eventos de el applicationContext a webContext?

+0

¿Encontró alguna solución para su problema? –

+0

Supongo que por diseño Spring no te permite hacer esto. De lo contrario, ¿no sería muy confuso si estás depurando qué clase manejó el evento? Ahora, en lugar de mirar dentro de un contenedor, debe buscar todos – gerrytan

Respuesta

3

Intente mover el publicador de eventos al archivo de contexto web, donde debe tener visibilidad en todo el contexto de la aplicación. Se produce un problema similar cuando configuring method security in the parent application context. El contexto de la aplicación principal (cargado por ContextLoaderListener) no tiene conocimiento del contexto secundario (web).

También puede usar un contexto de aplicación única para toda la aplicación si realmente no necesita la relación padre-hijo entre las dos. A menudo, se interpone en el camino y es más fácil si todos los granos se definieron en el mismo espacio.

+0

. Esta no puede ser la solución, porque la pregunta es cómo manejar los dos contextos. (No puedo mover las cosas de seguridad en el contexto web, porque explícitamente lo uso en la aplicación (es una aplicación con ACL)). – Ralph

+0

¿De verdad necesitas dos contextos de aplicación separados? Parece una situación en la que podría ser más simple tener una. –

+0

esto suena mucho mejor. Comprobaré por qué utilicé dos contextos y veré si puedo fusionarlos. – Ralph

2

Como se indica en la documentación para el marco de resorte, el mecanismo simple ApplicationEvent está diseñado solo para ser utilizado en el mismo contexto de aplicación, no estoy al tanto de que sea posible propagar eventos a contextos secundarios.

Si necesita una solución más avanzada, puede buscar una solución más avanzada como Java Message Service o Spring Integration.

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-functionality-events

0

podemos utilizar la etiqueta de importación para importar/puente de los 2 contextos diferentes creados de una manera la visibilidad de los eventos están disponibles/frijoles y compartido.

<import resource="applicationContext_name.xml"/> 

En este contexto, importe los XML que está configurado para ser creado a partir de ContextLoaderListener en el contexto de la xml DispatcherServlet.

4

Creo que la respuesta real es que es posible que desee configurar su aplicación de forma diferente (por lo que sólo tiene un contexto) Creo en su web.xml que tiene que hacer algo como esto:

<servlet> 
    <servlet-name>example</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>    
      classpath:/META-INF/applicationSpringConfig.xml 
     </param-value> 
    </init-param> 
</servlet> 

Pero para responder a la pregunta más profunda. Otra persona señala que puede usar includes en su archivo de primavera (de hecho, en el ejemplo anterior puede tener más de un Springconfig especificado en su servlet de despachador). Pero cuando incluye otros archivos de contexto, no comparte instancias de beans, solo definiciones.

Modularización Las aplicaciones de resorte han sido la única desventaja real de la primavera en comparación con EJB, etc. Eso llevó a la primavera a utilizar OSGi. Y la respuesta a su pregunta subyacente de cómo compartir el contexto de primavera, oficialmente comparte instancias Spring Bean entre contextos usando OSGi (dm de primavera)

6

Tuve el mismo problema, resolví el mío moviendo los beans creando el evento en la web -contexto.Sin embargo, puede resolver su problema cableando manualmente su detector de eventos, algo como esto (este código no se compila, por lo tanto no se ha probado):

@Component  
public class BeanInWebContext implements ApplicationListener<SomeEvent> { 

    @Autowired 
    private ApplicationContext webContext; 

    @PostConstruct 
    public void registerAsListener() { 
     // get parent context 
     AbstractApplicationContext appContext = (AbstractApplicationContext) webContext.getParent(); 
     // register self as a listener, this method is in AbstractApplicationContext 
     appContext.addApplicationListener(this); 
    } 

    @Override 
    public void onApplicationEvent(SomeEvent event) { 
    } 

} 
Cuestiones relacionadas