简体   繁体   English

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

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

I have studied many other StackOverflow posts on Spring autowire issues.我研究了许多其他关于 Spring 自动装配问题的 StackOverflow 帖子。 This question is not so simple as "don't expect @Autowire to work on an object you new ".这个问题并不像“不要指望@Autowire 能在你new的 object 上工作”那么简单。

I have a library that constructs objects from class names.我有一个从 class 名称构造对象的库。 The object classes must extend class F. The library is not built with Spring. object 类必须扩展 class F。该库不是用 Spring 构建的。 It accepts a class loader for resolving the class names.它接受 class 加载程序来解析 class 名称。 It is doing this:它正在这样做:

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

The library allows some context to be passed in. Here I provide the Spring ApplicationContext.该库允许传入一些上下文。这里我提供了 Spring ApplicationContext。 A particular subclass of F has code like this in its constructor: F 的一个特定子类在其构造函数中具有如下代码:

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

Class X is defined like this: Class X 定义如下:

    @Component
    public class X {

    private final Y ybean;

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

Class Y is another @Component. Class Y 是另一个@Component。

The sobject is able to call a method in the xbean (xbean is not null), but the ybean is null. sobject能够调用xbean中的方法(xbean不为null),但是ybean是null。 Why?为什么?

I thought that Spring constructed and wired up the @Components at application start time.我认为 Spring 在应用程序启动时构建并连接了@Components。 I expected that using an object from ApplicationContext would give me a completely built and wired up object.我希望使用 ApplicationContext 中的 object 会给我一个完全构建和连接的 object。

Updates 06/03/2020 I added an @PostConstruct as suggested in the first answer. 2020 年 6 月 3日更新我按照第一个答案中的建议添加了 @PostConstruct。 That showed that the object is getting constructed early in the life of the application.这表明 object 是在应用程序生命周期的早期构建的。

I tried disabling spring.devtools.restart.enabled with no change in behavior.我尝试禁用spring.devtools.restart.enabled而行为没有改变。

I tried disabling spring.main.lazy-initialization with no change in behavior.我尝试禁用spring.main.lazy-initialization而行为没有改变。

I removed spring-boot-devtools from my build.gradle with no change in behavior.我从 build.gradle 中删除了 spring-boot-devtools ,但行为没有任何变化。 However, the class loader being reported when the F objects and the Y bean are constructed is sun.misc.Launcher$AppClassLoader但是,构造F对象和Y bean时报告的class loader是sun.misc.Launcher$AppClassLoader

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

Your class Y will only be autowired, when it is also present in Springs' application context.您的 class Y 只有在 Springs 的应用程序上下文中也存在时才会自动装配。 Verify that you actually have your component scan configured so that it picks up your Y component.验证您确实配置了组件扫描,以便它拾取您的 Y 组件。 you can quickly verify this by adding a post consturct snippet to Y.您可以通过向 Y 添加一个后构造片段来快速验证这一点。

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

If your logger prints nothing, Y is definitely not loaded into the application context.如果您的记录器没有打印任何内容,则绝对不会将 Y 加载到应用程序上下文中。

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

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