将Spring bean注入EJB3

时间:2011-03-09 19:54:59

标签: spring dependency-injection ejb-3.1

我正在尝试使用@Interceptors(SpringBeanAutowiringInterceptor.class)将Spring bean注入EJB中,但我无法使用我见过的beanRefContext.xml示例。

这是我的EJB:

@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class AlertNotificationMethodServiceImpl implements
        AlertNotificationMethodService {

    @Autowired
    private SomeBean bean;
}

我提供了一个beanRefContext.xml,如下所示:

<?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。

java.lang.IllegalArgumentException: Cannot resolve ServletContextResource
without ServletContext

使用SpringBeanAutowiringInterceptor时,它不应该获取ApplicationContext而不是创建一个新的吗?

我也尝试更改我的web.xml,以便contextConfigLocation指向beanRefContext.xml,希望它加载我的Spring配置,但我最终得到了与上面相同的异常。

有谁知道如何正确地做到这一点?我看到的示例似乎使用了我正在使用的相同方法,我假设这意味着在调用Interceptor时正在重新创建bean(或者它是如何工作的,我误解了)。

1 个答案:

答案 0 :(得分:11)

  

使用SpringBeanAutowiringInterceptor时,是否应该获取ApplicationContext而不是创建新的?{/ p>

是的,这实际上就是它的作用。它使用ContextSingletonBeanFactoryLocator机制,后者又将许多ApplicationContext实例作为静态单例管理(是的,甚至Spring有时也必须求助于静态单例)。这些上下文在beanRefContext.xml中定义。

您的困惑似乎源于这些上下文与您的webapp ApplicationContext有任何关系的期望 - 他们没有,他们完全是分开的。因此,您的webapp ContextLoader正在基于app-config.xml中的bean定义创建和管理上下文,ContextSingletonBeanFactoryLocator创建另一个。{1}}。除非你告诉他们,否则他们不会沟通。 EJB无法掌握webapp的上下文,因为EJB位于该范围之外。

您需要做的是将需要由EJB使用的bean从app-config.xml移出到另一个bean定义文件中。这组提取的bean定义将构成新的ApplicationContext的基础,它将(a)由EJB访问,(b)将充当webapp上下文的父上下文。

要激活您的webapp上下文与新上下文之间的父子链接,您需要向名为<context-param>的{​​{1}}添加额外的web.xml。此参数的值应为parentContextKey中定义的上下文的名称(在您的示例中为beanRefContext.xml)。

在webapp的上下文中留下的bean将能够引用父上下文中的bean,EJB也是如此。但是,EJB将无法在webapp的上下文中引用任何内容。

此外,您无法在context中使用XmlWebApplicationContext,因为该类需要了解网络应用,而beanRefContext.xml无法提供该感知。你应该坚持使用ContextSingletonBeanFactoryLocator