@Resource有时不会在Spring中注入

时间:2013-03-18 01:51:24

标签: spring struts2

我有一个Spring / Struts2问题,我在Spring论坛上问过但没有回复 @Resource no injected sometimes

为了便于阅读,我将在此重复提问。希望它不被认为是垃圾邮件

当我使用@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出现问题。有一件事是肯定的,如果在E2 B遇到问题,它会不时发生,A和C不会有问题,或者至少在A和C上没有观察到问题。而且,如果A有5个@Resource字段,当问题发生时,访问第一个资源时可能会抛出NPE,但下一次可能是第二个资源。

这就是我的意思,问题只发生在“有时”。假设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
}

不知道是否有人遇到过此类问题。 如果需要其他信息,我会尽力提供。

由于

2 个答案:

答案 0 :(得分:0)

我之前在使用注释时遇到过类似的问题。这就是为什么我更喜欢在有限的情况下使用@Transactional。哪些类使用@Transactional注释?实现还是界面?

我只是通过调试器快速查看了这个,但我认为你最终可能会遇到多个bean,一个使用@Transactional-ly注释类创建的Spring代理,另一个在应用程序上下文中定义。我建议如果你在Spring配置文件中定义服务,你也可以在那里定义事务代理,并使用@Resource注释按名称注入代理,或者删除xml中的配置,并按类型注入你的注释。这样,如果您有无法解析的类型重复匹配,Spring将通知您。

答案 1 :(得分:0)

在这里做笔记 在这段时间之后,我还没有找到真正的原因和解决方案。

但是,时间已经证明升级到Spring 2.3.3或更高版本可以解决问题,或者至少问题尚未出现