java Spring 应用程序上下文为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36985189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:04:39  来源:igfitidea点击:

Spring application context is null

javaspringjavafxspring-boot

提问by Yunus Einsteinium

I am using Spring Boot 1.3.3, with JavaFX. The application successfully launches Splash screen with this(at this point applicationContext is not null)

我正在使用带有 JavaFX 的 Spring Boot 1.3.3。应用程序成功启动启动画面(此时 applicationContext 不为空)

@SpringBootApplication
public class PirconApplication extends Application{

@Bean(name = "primaryStage")
public Stage getPrimaryStage() {
    return new Stage(StageStyle.DECORATED);
}

private ConfigurableApplicationContext applicationContext = null;
private static String[] args = null;

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

@Override
public void start(Stage primaryStage) throws Exception {
    Task<Object> worker = worker();
    worker.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent event) {
            try {
                AppSplashController loader = applicationContext.getBean(AppSplashController.class);
                Stage stage = applicationContext.getBean(Stage.class);
                stage.setScene(loader.init());
                stage.initStyle(StageStyle.UNDECORATED);
                stage.show();
            } catch (IOException e) {
                    e.printStackTrace();
                    System.exit(0);
            }
        }
    });
    worker.setOnFailed(new EventHandler<WorkerStateEvent>() {

            @Override
            public void handle(WorkerStateEvent event) {
                    // TODO Auto-generated method stub
                    System.exit(0);
            }
    });
    worker.run();
}
public static void main(String[] args) {
    PirconApplication.args = args;
    launch(PirconApplication.class, args);
}

private Task<Object> worker() {
    return new Task<Object>() {
        @Override
        protected Object call() throws Exception {
                applicationContext = SpringApplication.run(PirconApplication.class, args);
                return null;
        }
    };
}
}

Problem is in AppSplashController applicationContext and primaryStage beans are all null.

问题在于 AppSplashController applicationContext 和 primaryStage beans 都是 null。

@Component
public class AppSplashController implements BootInitializable {

@FXML
private ImageView imgLoading;
@FXML
private Text lblWelcome;
@FXML
private Text lblRudy;
@FXML
private VBox vboxBottom;
@FXML
private Label lblClose;

private Stage primaryStage;

private ApplicationContext springContainer;
/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    System.out.println("applicationContext: "+springContainer);
    System.out.println("primaryStage: "+primaryStage);
}

}

@Autowired
@Override
public void setPrimaryStage(Stage primaryStage) {
    this.primaryStage = primaryStage;
}

@Override
public Scene init() throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource("/com/pircon/views/splash.fxml"));
    return new Scene(root);
}

@Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
    this.springContainer = ac;
}

}

BootInitializable interface

BootInitializable 接口

public interface BootInitializable extends Initializable, ApplicationContextAware {
    public Scene init() throws IOException; 
    public void setPrimaryStage(Stage primaryStage);
}

This is my first project in spring and spring boot, so pardon my ignorance.

这是我在 spring 和 spring boot 中的第一个项目,所以请原谅我的无知。

回答by vinayknl

I think you need specify spring to set autowire these beans. For example

我认为您需要指定 spring 来设置自动装配这些 bean。例如

@Autowired
private ApplicationContext springContainer;

Another suggestion is use ApplicationContextProvider which implements springs ApplicationContextAware interface.

另一个建议是使用实现 springs ApplicationContextAware 接口的 ApplicationContextProvider。

public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext context;

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        context = ctx;
    }
}

You can get the application context via ApplicationContextProvider.getApplicationContext();

您可以通过以下方式获取应用程序上下文 ApplicationContextProvider.getApplicationContext();

回答by Dinesh Lomte

Here is another way by which you can have ApplicationContext instance handy at the application level.

这是您可以在应用程序级别方便地使用 ApplicationContext 实例的另一种方法。

import org.springframework.context.ApplicationContext;

/**
 * @author Dinesh.Lomte
 *
 */
public enum AppContext {

    INSTANCE;

    public static AppContext getInstance() {
        return INSTANCE;
    }

    private ApplicationContext applicationContext;

    /**
     * Default constructor
     */
    private AppContext() {      
    }

    /**
     * 
     */
    public void setContext(ApplicationContext applicationContext) {     
        this.applicationContext = applicationContext;
    }

    /**
     * 
     * @return
     */
    public ApplicationContext getContext() {
        return applicationContext;
    }
}

Setting the ApplicationContext instance during the server startup or application launch.

在服务器启动或应用程序启动期间设置 ApplicationContext 实例。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import com.app.logger.AppLogger;
import com.app.util.AppContext;

/**
 * @author Dinesh.Lomte
 *
 */
@SpringBootApplication
@ComponentScan ({"com.app"})
public class RunSpringApplication {

    private static final AppLogger LOGGER = 
            new AppLogger(RunSpringApplication.class); 

    /**
     * @param args
     */
    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(
                RunSpringApplication.class, args);
        // Setting the application context for further references 
        AppContext.getInstance().setContext(applicationContext);

        LOGGER.info("------------------------------------------------");
        LOGGER.info("App started successfully.");                   
    }
}

Finally use the ApplicationContext instance in the classes based on your need.

最后根据需要在类中使用 ApplicationContext 实例。

ApplicationContext applicationContext = AppContext.getInstance().getContext();      
AppConfigProp appConfigProp = applicationContext.getBean(AppConfigProp.class);

MailConfigProp mailConfigProp = AppContext.getInstance().getContext()
            .getBean(MailConfigProp.class);