WebSphere 7中使用Spring(JSR 330注释)的依赖注入无效

时间:2013-02-05 13:31:54

标签: spring dependency-injection websphere code-injection jsr330

我有一个使用Java 6,Spring Framework 3.1.2和Mule-ESB 3.3.0构建的企业应用程序,以及与此问题无关的其他库。

我们的bean和服务都使用@Named@Inject JSR-330注释声明,分别用于自动组件扫描和依赖注入(没有EJB,只有服务bean)。当部署到JBoss 4.2.3(我们的测试环境)时,一切正常。但是,当部署到WebSphere 7中时,JSR-330注释似乎无法正常工作。标有@Named的bean根本就没有检测到。

我可以确保一切都配置正确(因为它在JBoss中工作)。具体来说,<context:component-scan />已正确定义base-package属性,并且scope-resolver属性已正确配置为使用Jsr330ScopeMetadataResolver(我们也尝试过没有它)。

我知道WebSphere 7(7.0.0.23)可能不支持这种注释。我还没有用@Component@Autowired Spring等价来测试它。不幸的是,我们非常希望使用JSR 330注释,因此即使我们在引擎盖下使用Spring Framework,我们的类也不会直接依赖于Spring。

尽管如此,虽然我花了一整天的时间来寻找WebSphere 7不支持JSR 330注释的明确声明,但到目前为止我还没有找到任何东西。

此外,我不明白为什么它不起作用,因为我假设Spring Framework是通过<context:component-scan />文件中的application-context.xml指令完成所有工作的人。

有人能为这个问题带来一些启示吗?

有没有办法通过WebSphere 7中的注释激活依赖注入?

如果我从JSR 330 @Named / @Inject注释切换回Spring自己的@Component@Autowired是否可能有效?

在绝望的尝试中,我可以扩展Spring的ComponentScanBeanDefinitionParser,以便即使在WebSphere 7中它也会检测JSR 330注释吗?

如果什么都不起作用,我最终将回归到纯XML配置。然而,这是非常不受欢迎的,因为将在XML中手动配置数百个bean。

3 个答案:

答案 0 :(得分:2)

WebSphere 8似乎是正确使用的版本;它支持EE6(WebSphere 7是EE5),后者又包含CDI 1.0(因此JSR 299)。

以下是来自DeveloperWorks的摘录,其中总结了WebSphere版本,JSR 299和JSR 300之间的关系

  

依赖注入是一种已经浮出水面的技术   在进入Java EE世界之前多次实现。   Spring Framework和Google Guice库很受欢迎   实现。在JSR 330中,尝试包括这些   进入J2SE平台的功能。 JSR 299是一个规范   使用JSR 330中定义的API并添加了更多功能   支持Java EE需求 IBM WebSphere Application Server V8和V8.5   (非Liberty配置文件)是完全兼容的Java EE 6容器和   实施JSR 299

答案 1 :(得分:2)

我最终通过扩展Sp​​ring Framework的Component Scan和Autowire功能提出了一种解决方法。

首先,我在组件扫描程序中添加了一个包含过滤器,以便@Named注释也被认为有资格检测并注册到Spring容器中:

<context:component-scan base-package="com.mycompany.mysystem">
    <context:include-filter type="annotation" expression="javax.inject.Named" />
</context:component-scan>

之后,我还向org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcesso‌​r添加了一个bean定义,将自动装配资格扩展到@Inject注释:

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
    <property name="autowiredAnnotationType" value="javax.inject.Inject" />
</bean>

最初,这可以很好地“重新激活”@Named@Inject注释。但是,在autowire候选解析过程中,我仍然存在一些与bean冲突的问题。这是由于Spring和JSR-330的默认解析过程的不同。这不是什么大问题,因为只有少数豆类陷入这种情况。通过添加一些策略性的@Qualifier注释来解决它们。

现在一切都很好,优雅,没有额外的配置。不过,我仍然不明白为什么会这样。我所知道的是,当我将应用程序部署到JBoss 4.2.3中时,会出现以下3行。另一方面,它们不会出现在WebSphere中:

INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] JSR-330 'javax.inject.Named' annotation found and supported for component scanning

DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
INFO  [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] JSR-330 'javax.inject.Inject' annotation found and supported for autowiring

我仍然不清楚为什么会发生这种情况,因为正如@Dreamer所说,这应该是Spring的责任,因此也不属于WebSphere业务。

如果有人确实有这样的线索,请指教我们。我相信参与讨论的每个人都会非常清楚。

答案 2 :(得分:-1)

同意duffymo,它应该适用于WS 7.由于Spring位于Websphere之上,所以Spring注释不属于webshere的业务(有点)。

您可能需要检查WS 7(即使您说每个配置都正确,因为它适用于JBoss),请点击您的应用程序 - &gt;点击Class loading and update detection,确保选中Classes loaded with local class loader first (parent last)。这将使服务器首先获取应用程序的库,然后是websphere的库。