简体   繁体   English

SpringBoot:Autowired 在配置中工作,但在控制器中返回 null

[英]SpringBoot: Autowired works in Configuration, but returns null in Controller

My Problem: I have created a Singleton Bean of my model Manager.我的问题:我已经为我的模型管理器创建了一个 Singleton Bean。 Trying to Autowire it in my Controller, however, results in a nullpointer.但是,尝试在我的控制器中自动装配它会导致空指针。 In my configuration, however, the Autowiring of the same Bean works just fine.然而,在我的配置中,同一个 Bean 的自动装配工作得很好。

I should note at this point that this is not the first singleton Bean I have made in this project;在这一点上我应该注意,这不是我在这个项目中制作的第一个单例 Bean; and as far as I can tell, I have made it in the same vein as all the others;据我所知,我和其他人一样。 which all Autowire correctly.所有 Autowire 正确。 That's the main reason why I'm stumped right now.这就是我现在被难住的主要原因。

The Code:编码:

The Main App is under the 'project' package, so all other packages are sub-packages of that one.主应用程序位于“项目”包下,因此所有其他包都是该包的子包。 I opted to omit the imports for brevity, but everything is imported as it should be.为简洁起见,我选择省略导入,但所有内容都按原样导入。

Config配置

package project.config

@Configuration
public class BootstrapConfig {
    
    @Bean
    @Scope("singleton")
    public ThingManager thingManager() {
        return new thingManager();
    }

   @Autowired
   private ThingManager manager;


   @PostConstruct
   public void initialize() {
     manager.setup() //This works fine.

  }
}

Manager经理

package project.model

public class ThingManager {

   private HashMap<String, Thing> things;

   public ThingManager() {
     things = new HashMap<String, Thing>();
   }

   public void setup() {
     //Do setup Things
   }

   public Thing getThing(String input) {
     return things.get(input);
   }

}

Controller控制器

package project.controller

@RestController
@RequestMapping("/api/things")
public class ThingController {

  @Autowired
  ThingManager manager; //This is null

  private Thing thing;

  public ThingController() {
    this.thing = manager.getThing("test"); //This then throws NullPointer.
  }

  @GetMapping("/")
  public ResponseEntity<Thing> showThing() {
    return ResponseEntity.ok(thing);
  }
}

What I have tried: I have tried marking ThingManager as @Component @Scope(value = "singleton") instead of setting up the Bean manually (so I removed the @Bean code-block in the configuration);我尝试过的:我尝试将 ThingManager 标记为@Component @Scope(value = "singleton")而不是手动设置 Bean(所以我删除了配置中的@Bean代码块); the result is the same;结果是一样的; Configuration can Autowire it perfectly fine, but Controller cannot.配置可以完美地自动装配它,但控制器不能。

I have looked at the myriad of posts about this topic already on here, but most seem to be about someone having forgotten to mark the class they Autowire in as a component or similar.我已经在这里查看了无数关于这个主题的帖子,但大多数似乎是关于有人忘记将他们 Autowire 所在的类标记为组件或类似的。 Maybe I overlooked a similarity to my problem;也许我忽略了与我的问题的相似之处; it's hard to tell.很难说。

Spring can autowire fields only after the object is created (the constructor is called), so you're accessing the manager in the constructor of ThingControler while it's not yet injected. Spring 只能在创建对象后自动装配字段(调用构造函数),因此您正在访问尚未注入 ThingControler 的构造函数中的manager The easiest way to use manager in the constructor would be to add it as a constructor parameter instead of autowiring (Spring will use available bean for the parameter):在构造函数中使用manager的最简单方法是将其添加为构造函数参数而不是自动装配(Spring 将使用可用的 bean 作为参数):

// ... 
public class ThingController {

  private final Thing thing;

  public ThingController(ThingManager manager) {
    this.thing = manager.getThing("test");
  }
  // ...
}

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

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