【问题标题】:Why Autowired annotation throws NullPointerException?为什么 Autowired 注解会抛出 NullPointerException?
【发布时间】:2021-02-15 04:34:20
【问题描述】:

我正在将 JavaFX 与 Spring Boot 结合起来。 我正在尝试自动装配的接口类。 我在网上浏览过这个问题,但到处都是由 NEW 运营商引起的问题。 我尝试了所有注释,但没有一个有效。 最奇怪的是 - 如果我将 ClassPathResource 直接放入 MyController 类,一切正常。

package com.fx.springfx.repository;
@Repository //@Component tried component too, same problem
public interface SettingsEntityRepository extends JpaRepository<SettingsEntity, Long> {

    SettingsEntity getByCode(String code);

}

我的控制器类

package com.fx.springfx.controller.admin;


@Component
public class MyController {

    @Autowired
    private SettingsEntityRepository settingsEntityRepository;//----- Here Always NULL

    @FXML
    private Button saveBtn;

    @FXML
    void initialize() {

        saveBtn.setOnAction(event -> {

            SettingsEntity p = new SettingsEntity("a", "123", "zxc");
            settingsEntityRepository.save(p);

        });

  }
}

我的主要课程

 package com.fx.springfx;

public class JavaFXApp extends Application {

    private ConfigurableApplicationContext context;

    @Override
    public void init() {
        ApplicationContextInitializer<GenericApplicationContext> initializer =
                context -> {
                    context.registerBean(Application.class, () -> JavaFXApp.this);
                    context.registerBean(Parameters.class, this::getParameters);
                    context.registerBean(HostServices.class, this::getHostServices);
                };
        this.context = new SpringApplicationBuilder()
                .sources(SpringfxApplication.class)
                .initializers(initializer)
                .run(getParameters().getRaw().toArray(new String[0]));
    }

    @Override
    public void start(Stage stage) throws IOException {
        this.context.publishEvent(new StageReadyEvent(stage));
    }

    @Override
    public void stop() throws Exception {
        this.context.close();
        Platform.exit();
    }
}

@Component
class StageInitializer implements ApplicationListener<StageReadyEvent> {

    private final String applicationTitle;
    private final ApplicationContext applicationContext;

    StageInitializer(@Value("${spring.application.ui.title}") String applicationTitle,
                     ApplicationContext applicationContext) {
        this.applicationTitle = applicationTitle;
        this.applicationContext = applicationContext;
    }

    @Override
    public void onApplicationEvent(StageReadyEvent stageReadyEvent) {
        try {
            Stage stage = stageReadyEvent.getStage();
            ClassPathResource fxml = new ClassPathResource("/fxml/admin/Login.fxml");
            //ClassPathResource fxml = new ClassPathResource("/fxml/admin/MyController.fxml");
            FXMLLoader fxmlLoader = new FXMLLoader(fxml.getURL());
            fxmlLoader.setControllerFactory(this.applicationContext::getBean);
            Parent root = fxmlLoader.load();
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.setTitle(this.applicationTitle);
            //stage.setMaximized(true);
            stage.show();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

class StageReadyEvent extends ApplicationEvent {

    private final Stage stage;

    StageReadyEvent(Stage stage) {
        super(stage);
        this.stage = stage;
    }

    public Stage getStage() {
        return stage;
    }
}


package com.fx.springfx;

@SpringBootApplication
public class SpringfxApplication {

    public static void main(String[] args) {
        //SpringApplication.run(SpringfxApplication.class, args);
        Application.launch(JavaFXApp.class, args);
    }


}

设置实体

package com.fx.springfx.entity;

@Entity
@Table(name = "Settings")
@Data
@NoArgsConstructor
public class SettingsEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Basic
    @Column(name = "CODE")
    private String code;
    @Basic
    @Column(name = "PORT")
    private String port;
    @Basic
    @Column(name = "INTERFACE")
    private String interfaceType;
    @Basic
    @Column(name = "SIMCARD")
    private String simCard;
    @Basic
    @Column(name = "ISMODEM")
    private boolean isModem;

    public SettingsEntity(String code, String port, String interfaceType) {
        this.code = code;
        this.port = port;
        this.interfaceType = interfaceType;
    }
}

【问题讨论】:

  • 因为@Autowired 尝试从上下文(即Spring Container)注入依赖,并且如果您不将您的类声明为候选bean,它将永远不会被扫描并且永远不会成为bean .因此 - Spring 应该注入什么?
  • 我试图将存储库类标记为组件和存储库,同样的问题
  • 如果由 Spring 正确管理,则不能为 null。由于这是在 Spring 更改注册某些内容之前由 JavaFX 管理的,因此在调用 init 时它将为空。在我看来,您的 JavaFX/Spring 集成是错误的(而且看起来过于复杂)。
  • null具体是什么?什么时候抛出异常?

标签: java spring-boot javafx autowired


【解决方案1】:

你需要在SettingsEntityRepository接口中添加@Component或者@Repository让spring知道它是一个自动布线的组件。

【讨论】:

  • 我试图将存储库类标记为组件和存储库,同样的问题
  • 那么设置实体呢?
  • 刚刚添加到帖子中
  • Spring Data JPA 有其他加载/检测所需存储库的方法。添加任一注释都不会解决任何问题。
猜你喜欢
  • 2014-12-18
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多