将Spring bean注入EJB3 [英] Inject Spring beans into EJB3
问题描述
我试图使用 @Interceptors(SpringBeanAutowiringInterceptor.class)
将Spring bean注入到EJB中,但是我无法使用 beanRefContext
I'm trying to inject Spring beans into an EJB using @Interceptors(SpringBeanAutowiringInterceptor.class)
but I cannot get it working with the beanRefContext.xml
examples I've seen.
这是我的EJB:
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class AlertNotificationMethodServiceImpl implements
AlertNotificationMethodService {
@Autowired
private SomeBean bean;
}
我提供了一个beanRefContext.xml,如下所示:
I've provided a beanRefContext.xml as follows:
<?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>
但是,似乎正在重新创建bean,而不是获取现有的ApplicationContext。我最终得到以下异常,因为我的一个bean是ServletContextAware。
But, it seems to be recreating the beans instead of obtaining the existing ApplicationContext. I end up with the following exception because one of my beans is ServletContextAware.
java.lang.IllegalArgumentException: Cannot resolve ServletContextResource
without ServletContext
使用 SpringBeanAutowiringInterceptor
,不应该获取ApplicationContext而不是创建一个新的?
When using the SpringBeanAutowiringInterceptor
, shouldn't it obtain the ApplicationContext instead of create a new one?
我也尝试更改我的web.xml,所以contextConfigLocation指向beanRefContext.xml,希望它'd加载我的Spring配置,但我最终得到与上述相同的异常。
I also tried changing my web.xml so the contextConfigLocation points to the beanRefContext.xml, hoping it'd load my Spring config but I end up with the same exception as above.
有没有人知道如何正确地做到这一点?我看到的例子似乎使用了我使用的相同方法,我认为这意味着当调用Interceptor时会重新创建bean(或者它是如何工作的,我被误解了)。
Does anyone know how to do this properly? The examples I've seen seem to use the same method I'm using which I assume means the beans are being recreated when the Interceptor is invoked (or is that how it's supposed to work and I've misunderstood).
推荐答案
当使用
SpringBeanAutowiringInterceptor
时,不应该获取ApplicationContext
而不是创建一个新的?
When using the
SpringBeanAutowiringInterceptor
, shouldn't it obtain theApplicationContext
instead of create a new one?
是的,这个实际上它是做什么的。它使用 ContextSingletonBeanFactoryLocator
机制,它又将多个 ApplicationContext
实例作为静态单例管理(是的,甚至Spring有时要诉诸静态单身人士)。这些上下文在 beanRefContext.xml
中定义。
Yes, and this is in fact what it does. It uses the ContextSingletonBeanFactoryLocator
mechanism, which in turn manages a number of ApplicationContext
instances as static singletons (yes, even Spring has to resort to static singletons sometimes). These contexts are defined in beanRefContext.xml
.
您的混淆似乎源于期望这些上下文有任何与您的webapp的 ApplicationContext
的关系 - 它们不是完全独立的。因此,您的webapp的 ContextLoader
正在根据 app-config.xml
中的bean定义创建和管理上下文, ContextSingletonBeanFactoryLocator
创建另一个。除非你告诉他们,否则他们不会沟通。 EJB无法掌握webapp的上下文,因为EJB位于该范围之外。
Your confusion seems to stem from the expectation that these contexts have any relation to your webapp's ApplicationContext
- they don't, they're entirely separate. So your webapp's ContextLoader
is creating and managing a context based on the bean definitions in app-config.xml
, and the ContextSingletonBeanFactoryLocator
creates another one. They won't communicate unless you tell them to. The EJBs cannot get hold of the webapp's context, since EJBs sit outside of that scope.
您需要做的是将需要使用的bean EJB从 app-config.xml
中转移到另一个bean定义文件中。提取的一组bean定义将构成新的 ApplicationContext
的基础,它将(a)由EJB访问,(b)将作为您的webapp的上下文
What you need to do is to move the beans that need to be used by your EJBs out of app-config.xml
and into another bean definition file. This extracted set of bean definitions will form the basis of a new ApplicationContext
which will (a) be accessed by the EJBs, and (b) will act as the parent context of your webapp's context.
为了激活您的webapp上下文和新上下文之间的父子链接,您需要添加一个额外的 context-param>
到您的 web.xml
调用 parentContextKey
。该参数的值应该是在 beanRefContext.xml
(即 context
)中定义的上下文的名称,在您的示例中)
In order to activate the parent-child link between your webapp's context and the new context, you need to add an additional <context-param>
to your web.xml
called parentContextKey
. The value of this parameter should be the name of the context defined in beanRefContext.xml
(i.e. context
, in your example).
在webapp上下文中保留的bean将能够引用父上下文中的bean,以及EJB。但是,EJB将无法引用webapp上下文中的任何内容。
The beans that stay behind in the webapp's context will be able to reference the beans in the parent context, as will the EJBs. However, the EJBs will not be able to reference anything in the webapp's context.
此外,您不能使用 XmlWebApplicationContext
在 beanRefContext.xml
中,因为该类需要对webapp的意识,而 ContextSingletonBeanFactoryLocator
无法提供该意识。你应该坚持使用 ClassPathXmlApplicationContext
。
Also, you cannot use XmlWebApplicationContext
in beanRefContext.xml
, since that class requires awareness of the webapp, and ContextSingletonBeanFactoryLocator
cannot supply that awareness. You should stick with ClassPathXmlApplicationContext
there.
这篇关于将Spring bean注入EJB3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!