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

标签 java spring spring-boot classloader applicationcontext

我研究了许多其他关于 Spring Autowiring 问题的 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 中的对象会 给我一个完全构建和连接的对象。

更新 2020 年 6 月 3 日 我按照第一个答案中的建议添加了 @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。

最佳答案

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

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

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

关于java - 为什么从 ApplicationContext 检索到的 bean 中的 @Autowire 为 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62175565/

相关文章:

java - 带有事务管理器和重试建议顺序的 Spring 监听器容器

azure - 如何在Azure云上部署Spring Cloud微服务

java - hadoop上的矩阵乘法

java - Wicket @SpringBean 不创建可序列化代理

java - 如何在struts中使用url对参数进行编码?

Java模块通信

java - Spring 3.1 或更高版本 @RequestMapping 消费/生产

java - Tomcat:无法找到或加载

java - Spring Boot 1.5.1 和 "The dependencies of some of the beans in the application context form a cycle"

java - Spring Cloud - Config Client 减慢指标/健康