将Spring bean注入EJB3 [英] Inject Spring beans into EJB3

查看:218
本文介绍了将Spring bean注入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 the ApplicationContext 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆