繁体   English   中英

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

[英]Why is an @Autowire null in a bean retrieved from ApplicationContext?

我研究了许多其他关于 Spring 自动装配问题的 StackOverflow 帖子。 这个问题并不像“不要指望@Autowire 能在你new的 object 上工作”那么简单。

我有一个从 class 名称构造对象的库。 object 类必须扩展 class F。该库不是用 Spring 构建的。 它接受 class 加载程序来解析 class 名称。 它正在这样做:

     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);

Class X 定义如下:

    @Component
    public class X {

    private final Y ybean;

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

Class Y 是另一个@Component。

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

我认为 Spring 在应用程序启动时构建并连接了@Components。 我希望使用 ApplicationContext 中的 object 会给我一个完全构建和连接的 object。

2020 年 6 月 3日更新我按照第一个答案中的建议添加了 @PostConstruct。 这表明 object 是在应用程序生命周期的早期构建的。

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

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

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

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

您的 class Y 只有在 Springs 的应用程序上下文中也存在时才会自动装配。 验证您确实配置了组件扫描,以便它拾取您的 Y 组件。 您可以通过向 Y 添加一个后构造片段来快速验证这一点。

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

如果您的记录器没有打印任何内容,则绝对不会将 Y 加载到应用程序上下文中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM