2

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

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

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

我知道 WebSphere 7 (7.0.0.23) 可能不支持这种注释。我还没有用 Spring 等价物对其@Component进行测试。@Autowired不幸的是,我们非常希望使用 JSR 330 注释,这样我们的类就不会直接依赖于 Spring,即使我们在底层使用了 Spring Framework。

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

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

任何人都可以为这个问题带来一些启示吗?

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

如果我从 JSR 330 @Named/@Inject注释切换回 Spring 自己的注释,@Component@Autowired可能会起作用吗?

在绝望的尝试中,我是否可以扩展 SpringComponentScanBeanDefinitionParser以使其即使在 WebSphere 7 中也能检测到 JSR 330 注释?

如果没有任何效果,我最终将退回到纯 XML 配置。然而,这是非常不可取的,因为将有数百个 bean 需要在 XML 中手动配置。

4

3 回答 3

2

我最终通过扩展 Spring 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>

之后,我还向 中添加了一个 bean 定义org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcesso‌​r,将自动装配资格扩展到@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 业务。

如果有人确实有这样的线索,请赐教。我敢肯定,这对参与此讨论的每个人都会非常清楚。

于 2013-02-06T10:13:46.170 回答
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

于 2013-02-05T15:38:41.210 回答
-1

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

您可能需要在 WS 7 上检查的一件事(即使您说每个配置在 JBoss 上工作时都是正确的)是单击您的应用程序 -> 单击Class loading and update detection,确保Classes loaded with local class loader first (parent last)已选中。这将使服务器首先获取应用程序的库,然后是 websphere 的库。

于 2013-02-05T21:54:07.730 回答