spring - Inyectar frijoles primavera en EJB3
dependency-injection ejb-3.1 (1)
Al usar el
SpringBeanAutowiringInterceptor
, ¿no debería obtenerApplicationContext
lugar de crear uno nuevo?
Sí, y esto es de hecho lo que hace. Utiliza el mecanismo ContextSingletonBeanFactoryLocator
, que a su vez gestiona varias instancias de ApplicationContext
como singleton estáticos (sí, incluso Spring tiene que recurrir a singleton estáticos a veces). Estos contextos se definen en beanRefContext.xml
.
Su confusión parece derivarse de la expectativa de que estos contextos tienen alguna relación con el ApplicationContext
de su ApplicationContext
web; no es así, están completamente separados. Por lo tanto, el ContextLoader
su aplicación web está creando y administrando un contexto basado en las definiciones de bean en app-config.xml
, y ContextSingletonBeanFactoryLocator
crea otro. No se comunicarán a menos que usted les diga que lo hagan. Los EJB no pueden controlar el contexto de la aplicación web, ya que los EJB se encuentran fuera de ese alcance.
Lo que debe hacer es mover los beans que necesitan los EJB de app-config.xml
hacia otro archivo de definición de bean. Este conjunto extraído de definiciones de bean formará la base de un nuevo ApplicationContext
cual (a) accederán los EJB, y (b) actuará como el contexto principal del contexto de su aplicación web.
Para activar el enlace padre-hijo entre el contexto de su webapp y el nuevo contexto, necesita agregar un <context-param>
adicional a su web.xml
llamado parentContextKey
. El valor de este parámetro debe ser el nombre del contexto definido en beanRefContext.xml
(es decir, context
, en su ejemplo).
Los beans que se quedan en el contexto de la aplicación web podrán hacer referencia a los beans en el contexto primario, al igual que los EJB. Sin embargo, los EJB no podrán hacer referencia a nada en el contexto de la aplicación web.
Además, no puede usar XmlWebApplicationContext
en beanRefContext.xml
, ya que esa clase requiere conocimiento de la aplicación web, y ContextSingletonBeanFactoryLocator
no puede proporcionar esa información. Debería quedarse con ClassPathXmlApplicationContext
allí.
@Interceptors(SpringBeanAutowiringInterceptor.class)
inyectar Spring beans en un EJB usando @Interceptors(SpringBeanAutowiringInterceptor.class)
pero no puedo hacerlo funcionar con los ejemplos de beanRefContext.xml
que he visto.
Aquí está mi EJB:
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class AlertNotificationMethodServiceImpl implements
AlertNotificationMethodService {
@Autowired
private SomeBean bean;
}
He proporcionado un beanRefContext.xml de la siguiente manera:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="...">
<!-- Have also tried with ClassPathXmlApplicationContext -->
<bean id="context"
class="org.springframework.web.context.support.XmlWebApplicationContext">
<property name="configLocations" value="/config/app-config.xml" />
</bean>
</beans>
Pero, parece estar recreando los beans en lugar de obtener el ApplicationContext existente. Termino con la siguiente excepción porque uno de mis beans es ServletContextAware.
java.lang.IllegalArgumentException: Cannot resolve ServletContextResource
without ServletContext
Al usar el SpringBeanAutowiringInterceptor
, ¿no debería obtener ApplicationContext en lugar de crear uno nuevo?
También traté de cambiar mi web.xml para que el contextConfigLocation apunte a beanRefContext.xml, con la esperanza de que cargue mi configuración de Spring pero termino con la misma excepción que la anterior.
¿Alguien sabe cómo hacer esto correctamente? Los ejemplos que he visto parecen usar el mismo método que estoy usando, y supongo que significa que los beans se vuelven a crear cuando se invoca el interceptor (o es así como se supone que debe funcionar y no he entendido bien).