为什么从ApplicationContext检索的bean中@Autowire为空?

问题描述 投票:0回答:1

我研究了有关Spring autowire问题的许多其他StackOverflow帖子。这个问题并不像“不要期望@Autowire在您new的对象上工作”那样简单。

我有一个根据类名构造对象的库。对象类必须扩展类F.库不是用Spring构建的。它接受用于解析类名称的类加载器。它正在这样做:

     Class<?> someClass = Class.forName(className, true, classLoader);
     if (F.class.isAssignableFrom(someClass)) {
          Class<? extends F> fClass = (Class<? extends F>) someClass; 
          Constructor constructor = fClass.getConstructor(FMap.class, Object.class);
          F fobject = (F) constructor.newInstance(parameterMap, applicationContext);
      ...

该库允许传递一些上下文。在这里,我提供了Spring ApplicationContext。F的特定子类在其构造函数中具有如下代码:

    ApplicationContext applicationContext = (ApplicationContext)context;
    X xbean = (X)applicationContext.getBean("xbean");
    S sobject = new S(xbean);

X类的定义如下:

    @Component
    public class X {

    private final Y ybean;

    @Autowired
    public X(Y ybean) {
        this.ybean = ybean;
    }
    ...

Y类是另一个@Component。

sobject可以调用xbean中的方法(xbean不为null),但是ybean为null。为什么?

我以为Spring在应用程序启动时就构建并连接了@Components时间。我期望使用ApplicationContext中的对象给我一个完全建造并连接好的物体。

更新06/03/2020我按照第一个答案的建议添加了@PostConstruct。这表明该对象是在应用程序生命周期的早期构造的。

我尝试禁用spring.devtools.restart.enabled,但行为没有改变。

我尝试禁用spring.main.lazy-initialization,但行为没有改变。

我从build.gradle中删除了spring-boot-devtools,但没有任何行为改变。但是,在构造F对象和Y bean时报告的类加载器为sun.misc.Launcher$AppClassLoader

我们正在运行org.springframework.boot:spring-boot-starter-web:2.2.6.RELEASE。

java spring classloader applicationcontext
1个回答
0
投票

您的类Y仅在Springs的应用程序上下文中也存在时才自动装配。验证您是否实际配置了组件扫描,以使其拾取Y组件。您可以通过向Y添加构造后代码段来快速验证这一点。

@PostConstruct
void init() {
   logger.info("Here I am");
}

如果您的记录器什么也不打印,则肯定不会将Y加载到应用程序上下文中。

© www.soinside.com 2019 - 2024. All rights reserved.