Spring bean 在扩展的类中为空

问题描述

我已经用很多方法搜索过这个,但找不到任何与之相关的东西。 我遇到了一个问题,即另一个 bean(已扩展)中的 spring bean 没有被自动装配

我拥有的是这个:

interface A {
}

@Service
class B implements A {
    @Autowired
    private RandomSpringBean randomSpringBean;
}

@Primary
@Service
class C extends B {
    
}

发生的事情是,当 B 中的 RandomSpringBean 被另一个自动装配 B 的类调用时,它不会被自动装配,而只是被自动装配 C 的类调用,就像这样:

class D {
    @Autowired
    private B b;//beans inside B are null
}

class E {
    @Autowired
    private C c;//beans inside B (C subclass) are not null
}

D 和 E 都在其他类中自动装配。 如果我注释掉/删除 C,B 将恢复正常工作。

我希望这不会太令人困惑。

Ps:我不是这么干的,是别人干的。我只是遇到了这个问题,想知道一种解决方法,也许不会让 C 停止扩展 B。

解决方法

如果您没有使用 @Qualifier / @Primary 或类似结构,这部分代码应该会给您带来问题:

class D {
     @Autowired
     private B b;
}

异常类似于:

Field b in my.boring.package.beandemo.D required a single bean,but 2 were found:

这是一个工作演示:

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
public class MyBeans {
    
    @Component
    public static class RandomBean {}
    
    public static interface A {}
    
    @Component("B")
    public static class B implements A {
        
        @Autowired
        RandomBean randomBean;
    }
    
    @Component
    public static class C extends B {}
    
    @Component
    public static class D {
        
        @Autowired
        @Qualifier("B")
        private B b;
        
        @PostConstruct
        public void checkRandomBean() {
            if (b.randomBean != null) {
                System.out.println("B has randomBean");
            }
        }
    }
    
    @Component
    public static class E {
        
        @Autowired
        private C c;
        
        @PostConstruct
        public void checkRandomBean() {
            if (c.randomBean != null) {
                System.out.println("C has randomBean");
            }
        }
    }
}

编辑:

请检查 D 中 B 的运行时类。

由于 C 是用 @Primary 注释的,所以应该将 C 的一个实例注入 D。

C 也不能访问 B 的私有字段。