我有一个 Spring/Struts2 问题,我在 Spring 论坛中询问过,但没有回复 @Resource 有时没有注入
为了便于阅读,我将在这里重复这个问题。希望它不被视为垃圾邮件
当我使用 @Resource 注入 bean 时,我遇到了一个非常奇怪的问题。我正在使用 Struts2 2.2.3.1 和 Spring 3.0.0 提供的 Spring 插件。(我无法在不知道正确原因的情况下升级到最新版本的 Spring,因为所有程序都在生产中)
问题或观察到的问题是当创建 Struts2 Action 时,使用 @Resource 注释的字段应该具有 Spring 注入的资源。但是,有时且仅有时其中一个带注释的资源未注入或值为 null,因此会导致 NullPointerException。问题发生的点未确定,这意味着在不同环境中运行的同一组程序将导致不同的行为。此外,未注入的资源并不总是相同的。例如,如果有动作 A、B、C 和环境 E1 和 E2,则在 E1 中,A 动作有时可能会出现此问题,而在 E2 中,可能是动作 B 出现问题。一件事'
这就是我所说的问题只“有时”发生的意思。假设 A 遇到这种问题,我启动 Web 服务器(tomcat 或 WAS),如果出现问题,我会第一次访问 A,它将在整个服务器启动期间发生。如果我第一次访问 A 时没有出现问题,那么在此服务器启动的整个过程中都不会出现问题。此外,如果这次它是第一个没有注入的资源,那么这次启动也是一样的。
这是我的一些应用程序设置:我将 XML 与注释扫描混合使用。基本上所有的 Action、Service、Dao 类都在 XML 中定义,但是所有属性定义都留给 Spring 扫描实际类。
样本定义:
代码:
<!-- have this in all XML files -->
<context:annotation-config/>
<!-- an action definition, all actions are scoped prototype. It will use adm.common.admBranchesManager in the action with field annotated with @Resource -->
<bean id="adm.common.chooseBranchAction" class="com.bi.wms.adm.common.web.ChooseBranchAction" scope="prototype"></bean>
<!-- all service and dao are singleton and do not have any problem, all service/Manager are annotated with @Transactional. In Action we only code against interface and not actual concrete class -->
<bean id="adm.common.admBranchesManager" class="com.bi.wms.adm.common.service.impl.AdmBranchesManagerImpl"/>
<bean id="adm.common.admBranchesDao" class="com.bi.wms.adm.common.dao.jdbc.AdmBranchesDaoImpl"/>
此外,对于所有操作,它们都扩展了一个抽象操作,该操作具有会话范围的资源字段。
代码:
<bean id="base.wms.login" class="com.bi.wms.common.model.WmsLogin" destroy-method="logout" scope="session">
<aop:scoped-proxy />
<property name="admUserSessionsManager" ref="adm.operation.admUserSessionsManager"/>
</bean>
这是示例操作的一部分: 代码:
//this class is just a sample not the actually one thats having the problem, AbstractWmsAction is the class that have a session-scoped bean
public class AdmWmsControlAction extends AbstractWmsAction
{
@Resource(name = "adm.operation.admWmsBatchGroupsManager")
private AdmWmsBatchGroupsManager admWmsBatchGroupsManager;
@Resource(name = "adm.operation.admWmsControlManager")
private AdmWmsControlManager admWmsControlManager;
//sometimes we use setters for injecting but that doesnt stop the problem from happening
//....omit
}
不知道有没有人遇到过这种问题。如果需要更多信息,我会尽力提供。
谢谢