Spring @春季有时未注入资源

Spring @春季有时未注入资源,spring,struts2,Spring,Struts2,我有一个Spring/Struts2问题,我在Spring论坛上问过,但没有回应 为了便于阅读,我将在这里重复这个问题。希望这不是垃圾邮件 当我使用@Resource注入bean时,我遇到了一个非常奇怪的问题。 我正在使用Struts2.2.3.1和Spring3.0.0提供的Spring插件。(我无法在不知道正确原因的情况下升级到Spring的最新版本,因为所有程序都在生产中) 问题或观察到的问题是,当创建Struts2操作时,用@Resource注释的字段应该由Spring注入资源。但是,

我有一个Spring/Struts2问题,我在Spring论坛上问过,但没有回应

为了便于阅读,我将在这里重复这个问题。希望这不是垃圾邮件

当我使用@Resource注入bean时,我遇到了一个非常奇怪的问题。 我正在使用Struts2.2.3.1和Spring3.0.0提供的Spring插件。(我无法在不知道正确原因的情况下升级到Spring的最新版本,因为所有程序都在生产中)

问题或观察到的问题是,当创建Struts2操作时,用@Resource注释的字段应该由Spring注入资源。但是,有时,也只是有时,一个带注释的资源没有被注入,或者该值只是null,因此会导致NullPointerException。问题发生的点尚未确定,这意味着在不同环境中运行的同一组程序将导致不同的行为。另外,未注入的资源并不总是相同的。 例如,如果存在动作A、B、C以及环境E1和E2,则在E1中,动作A有时可能有此问题,而在E2中,可能是动作B有此问题。可以肯定的是,如果E2中B出现问题,它会不时发生,A和C不会出现问题,或者至少A和C没有发现问题。此外,如果A有5个@资源字段,当问题发生时,访问第一个资源时可能会抛出NPE,但下一次可能是第二个资源

这就是我所说的问题“有时”才会发生的意思。假设A有这种问题,我启动web服务器(tomcat或WAS),第一次访问A,如果问题发生,它将在整个服务器启动期间发生。如果问题在我第一次访问A时没有发生,那么在整个服务器启动期间,问题不会发生。此外,如果这一次它是第一个没有注入的资源,那么对于这个启动来说也是一样的

以下是我的应用程序设置: 我将XML与注释扫描混合使用。基本上,所有的动作、服务和Dao类都是用XML定义的,但是所有的属性定义都留给Spring来扫描实际的类

示例定义:

代码:

我不知道是否有人有这种问题。 如果需要更多信息,我将尽力提供


谢谢

我以前见过Spring使用注释时出现类似问题。这就是为什么我喜欢在有限的情况下使用@Transactional。哪些类用@Transactional注释?实现还是接口

我只是通过调试器快速了解了这一点,但我认为最终可能会出现多个bean,一个是使用@Transactional--ly注释类创建的Spring代理,另一个是在应用程序上下文中定义的。我建议,如果您在Spring配置文件中定义服务,您也可以在那里定义事务代理,并使用@Resource注释按名称插入代理,或者删除xml中的配置,并在注释中按类型插入。这样,如果您有无法解析的重复匹配项,Spring会通知您 经过这些时间,我还没有找到真正的原因和解决办法


然而,时间已经证明,升级到Spring 2.3.3或更高版本可以解决问题,或者至少问题还没有出现

您如何在代码中找到注释?抱歉,我不确定“查找注释”是什么意思,您是指Spring如何找到我的注释?我认为,当我在SpringXML中定义bean时,Spring会自动扫描类,似乎就是这样,为什么不让它这样做呢。还有,为什么您认为应该使用Spring来注入其他bean的引用呢?我让Spring为我找到我的注释。我使用Spring只是为了一个选择,我不认为我“应该”或不应该。我只是在使用它。你为什么要使用
@Resource
呢?因为它使bean成为
@Repository
,并让Spring自动连接依赖项。我的所有@Transactional都在我的服务级别实现类中,我的所有操作代码都只针对接口。对不起,我可能不太了解春天。我不明白Spring代理如何创建@Transactional注释类以及在我的应用程序上下文中定义的类,因为我只使用context:annotation-config,而不使用context:component-scan。我确实指明了,那有关系吗?还没有。我已经为Spring设置了日志,但是由于我已经设置了日志,所以这个问题还没有发生。我正在尝试登录到其他站点上的项目并查看。你对我之前的评论有什么想法吗?当你使用任何基于方面的特性(JDBC模板、事务等)时,Spring总是创建一个代理。我在过去看到的是-没有编码/注入到接口和/或在实现上使用与服务类不匹配的事务公共方法。这可能会导致spring创建一个与您的接口不匹配的代理,因此无法在事务中适当地包装该类。正如我所说,我的首选是使接口具有事务性,然后我可以确定被注入的接口是我定义的接口,而不是代理。我确定我们只注入接口,但是我将检查是否有任何标记为事务的接口不在接口上。但您的意思是在接口上添加事务性注释,而不是具体的类?但我认为Spring建议我们将事务性注释放在具体类上。只是出于好奇,您是否有context:component scan元素来扫描包含Spring注释类的包?@Atul我们不使用注释来定义bean,我们只使用注释来定义依赖项,所有bean都是用xml定义的,我们有
<!-- 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
}