我有这些 bean :
<bean id="Child" class="test.Child"></bean>
<bean id="Parent" class="test.Parent">
<property name="child" ref="Child" />
</bean>
我在 Tomcat 上使用 Axis2、Spring 和 Hibernate。 Axis 服务位于父 bean 中。它在 services.xml 中映射为 SpringBeanName,包括正确的 ServiceClass。我将日志放在父 bean 中子 bean 变量的 get 和 set 方法中:
private Child child;
public void setChild(Child child) {
this.child = child;
System.out.println(child);
}
public Child getChild() {
System.out.println(child);
return child;
}
我有一个在启动时调用的 Spring 初始化服务,用于在实现 ServiceLifeCycle 的服务的 startUp 方法中加载 Spring。
ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
new String[] { "classpath:spring/applicationContext.xml" }, false);
applicationContext.setClassLoader(classLoader);
applicationContext.refresh();
这是一个简单的示例项目,因为实际逻辑要复杂得多。不管怎样,结果是:
- 在 Axis2 war 分发的服务中部署 AAR,一切都完美加载,set 方法实际上是用非空对象调用的。
- 每次调用该服务时,都会成功读取 child。
问题出在 Tomcat 重新启动时。在起始日志中,使用非空对象调用 set 方法。但是当服务被调用时——空指针异常,child 为空。重新部署 AAR 会使一切重新正常工作。但是在重新启动之后 - child 再次为空。
发生了什么?我们将不胜感激。
注意:我不使用 new 创建子项。 beans 的所有范围都是默认的。我尝试使用原型(prototype)范围但没有成功。 session 和请求范围引发了无法识别这些范围的异常:
没有为范围“...”注册范围
注意 2:取消注释 conf 文件夹中 context.xml 中的标记并没有改变任何内容。改完后我重启了Tomcat。
最佳答案
虽然我找到了解决方案,但它并未涵盖所有情况。将 services.xml
中的服务范围从 application
更改为 request
(或其他两个)解决了这个看起来有点合乎逻辑的问题.
注意:如果 application
范围是您真正需要的,则此修复不适用。
关于java - Tomcat 使用 Spring 和 Axis2 重新启动后,注入(inject)的 bean 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21633548/