java – 嵌套类中的Spring注入bean null

我有一个包含2个静态嵌套类的类,它们对2种不同的泛型类型执行相同的操作.

我将这两个类暴露为bean,并像通常那样为构造函数添加了@Autowired.

这是基本设置

abstract class <T> Parent implements MyInterface<T> {
   private final Service service;
   Parent(Service service){ this.service = service; }

   @Override public final void doInterfaceThing(T thing){
     T correctedT = map(thing);
     service.doTheThing(correctedT);
   }

   protected abstract T map(T t);

   @Service
   public static class ImplA extends Parent<A> {
     @Autowired ImplA (Service service){ super(service); }
     A map(A a){ //map a }
   }

   @Service
   public static class ImplB extends Parent<B> {
     @Autowired ImplB (Service service){ super(service); }
     B map(B b){ //map b }
   }

}

在我的另一堂课中

@Service
public class Doer {
   private final List<MyInterface<A>> aImpls;
   @Autowired public Doer(List<MyInterface<A>> aImpls){ this.aImpls = aImpls; }
   public void doImportantThingWithA(A a){
     aImpls.get(0).doInterfaceThing(a);
   }
}

当我运行应用程序时,所有内容似乎都正确注入,当我在ImplA和ImplB构造函数中放置断点时,我的“服务”值为非null值.我在Doer的aImpls列表中也有一个ImplA bean.

当我调用doImportantThingWithA(a)时,ImplA中的“service”为空,我显然死了.

我不确定这是怎么可能的,因为:

>我在构造函数中看到一个非空值,用于服务,这是一个最终字段.
>如果spring将ImplA和ImplB注入另一个类,它应该已经将一个Service注入ImplA或ImplB,或者在bean初始化时抛出异常.我没有设置懒惰加载和所有bean依赖项是必需的.

嵌套类的原因是因为2个实现之间唯一的变化是map()函数.试图避免1行不同代码的额外类.

更多信息:
当我在Parent.doInterfaceThing()中添加一个断点时,如果我在“service”上添加一个监视,我将得到null作为值.如果我添加一个getService()方法,然后调用getService()而不是直接引用this.service,我得到正确的服务bean.我不知道这个含义,但代理似乎很奇怪.

最佳答案 看起来导致问题的是Parent.doInterfaceThing();

如果我从方法签名中删除final,则会正确填充“service”字段,并且代码按预期工作.

我完全不明白为什么更改方法签名会影响我班级中最终字段的注入值…但它现在有效.

点赞