1

我有一个父抽象类和一个具体的子类。抽象的有一个具体方法和另一个抽象方法,子类实现。这两个类都配置为 Spring bean。代码片段类似于以下内容:

弹簧配置:

<bean id="parent" class="Parent" abstract="true">
  <property name="propA" ref="propA"/>
  <property name="cacheMan" ref="cacheMan"/>
</bean>

<bean id="child" class="Child" parent="parent">
  <property name="propB" ref="propB"/>
  <property name="cacheMan" ref="cacheMan"/>
</bean>

<!-- Of course, cacheMan is defined elsewhere and not relevant here.-->

类定义:

    public abstract class Parent {
      private A propA; // A is irrelevant.
      private CacheManager cacheMan; // This is the object in question.
      public void doProcess1() {
         //code logic
         if (cacheMan == null) {
            // Error!
         }
      }
      public void doProcess2();
    }

    public class Child extend Parent {
      private B propB; // Again, B is irrelevant.
      private CacheManager cacheMan; // This is the object in question.
      public void doProcess2() {
         //code logic
      }
    }


public class Test {
        private Parent parent; //Assume this is Spring injected and it's of type Child.
        public void doTest() {
          parent.doProcess1(); // Error thrown since cacheMan is null.
        }
}

这两个类都有适当的 getter/setter 方法cacheMan。我不明白cacheMan该方法中的空值如何doProcess1()。但是,如果我从

cacheMan == nullto getCacheMan() == null,不抛出错误。

我认为getCacheMan()正在检索注入到子类的对象,因为parent它是实例Child,这就是它不为空的原因。

请对此有所了解,如果不清楚,请告诉我。

4

1 回答 1

2

这个问题与 Spring 无关,而是与 Java 语言有关——具体的方法覆盖。

setCacheMan()在抽象父类和子类中都定义了(这就是我的假设)方法。当 Spring 调用该方法时,它总是在 child 中调用覆盖的版本——并且该版本也会修改cacheManchild 中的引用。cacheMan父级中的引用从未真正被触及,因为访问它的唯一方法在子级中被覆盖。

如果我将该行从 更改cacheMan == nullgetCacheMan() == null,则不会引发错误。

从已经说过的内容来看,这很明显 -getCacheMan()也被覆盖了!cacheMan父项中的引用是null(见上文),但由于getCacheMan()被覆盖,它cacheMan在子项中访问,而不是在父项中。实际上,您有两个变量,但 child 中的那个不能更新。

解决方案:父 bean 的想法是在一个地方有共同的依赖,并避免在每个孩子中重复它们:

<bean id="parent" class="Parent" abstract="true">
  <property name="propA" ref="propA"/>
  <property name="cacheMan" ref="cacheMan"/>
</bean>

<bean id="child" class="Child" parent="parent">
  <property name="propB" ref="propB"/>
</bean>

并且要么声明cacheMan受保护,要么至少具有受保护的吸气剂,以便子类可以访问它。不要cacheMan在子类中创建字段。

于 2012-04-24T22:11:40.913 回答