Java - Spring Autowired分配null

时间:2017-01-18 09:25:01

标签: java xml spring javafx

我试图使用spring xml配置(仅用于自动装配一些对象 - 业务逻辑类和jdbcTemplate)和javafx,但每当我使用@Autowired时,对象都变为空。

这是我的主类代码:

@Component
public class App extends Application {

    public static ApplicationContext appContext;
    public static Stage window;

    static {
        appContext = new ClassPathXmlApplicationContext("spring//beans.xml");
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        System.out.println("test1");
        window = primaryStage;
        Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("scenes/Login.fxml"));
        Scene scene = new Scene(root);
        primaryStage.setTitle(Titles.APPLICATION_TITLE);
        primaryStage.setScene(scene);
        primaryStage.show();
        window.setOnCloseRequest(e -> closeProgram(e));
        System.out.println("test2");
    }

    private void closeProgram(WindowEvent windowEvent) {
        try {
            windowEvent.consume();
            CommonUtility.openNewWindow("ConfirmExit", Titles.APPLICATION_TITLE);
        } catch (IOException e) {
            e.printStackTrace();
        }
}
}

Spring配置文件,beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
    <context:annotation-config />
    <context:component-scan base-package="in.csitec.sp" />

    <import resource="classpath:database-config1.xml" />

    <bean id="taskExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="5" />
        <property name="maxPoolSize" value="20" />
        <property name="queueCapacity" value="25" />
        <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    </bean>


</beans>

登录控制器:

@Component
public class LoginController implements Initializable {


    @FXML
    private Label statusLabel;

    @FXML
    private TextField usernameTextField, passwordTextField;

    @FXML
    private Button loginButton;

    @FXML
    private ProgressBar progressBar;

    private Task<Object> loginTask;

    public static String loggedInUser;

    @Autowired
    LoginManager loginManager;

    @Override
    public void initialize(URL location, ResourceBundle resources) {


    }

    public void onLoginButtonClick(ActionEvent actionEvent){
        if (usernameTextField.getText().isEmpty()) {
            statusLabel.setText(Messages.EMPTY_USERNAME);
            NotificationManager.showNotification(Titles.APPLICATION_TITLE, Messages.EMPTY_USERNAME);
            return;
        }
        if (passwordTextField.getText().isEmpty()) {
            statusLabel.setText(Messages.EMPTY_PASSWORD);
            NotificationManager.showNotification(Titles.APPLICATION_TITLE, Messages.EMPTY_PASSWORD);
            return;
        }
        loginButton.setDisable(true);

        progressBar.setProgress(0);

        loginTask = createLoginTask();

        progressBar.progressProperty().unbind();
        progressBar.progressProperty().bind(loginTask.progressProperty());


        loginTask.messageProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

                if(LoginManager.statusCode.equalsIgnoreCase("1")){
                    System.out.println("Invalid username or password.");
                    progressBar.progressProperty().unbind();
                    loginButton.setDisable(false);
                    return;
                }
                System.out.println("Logged in successfully");
                progressBar.progressProperty().unbind();
                loginButton.setDisable(false);
            }
        });
        new Thread(loginTask).start();
    }

    private Task<Object> createLoginTask() {

        return new Task<Object>() {

            @Override
            protected Object call() throws Exception {
                try{
                    Map<String, String> requestMap = new HashMap<>();
                    requestMap.put(Constants.USERNAME, usernameTextField.getText());
                    requestMap.put(Constants.PASSWORD, passwordTextField.getText());
                    loginManager.loginManager(requestMap);
                    updateProgress(100, 100);
                    updateMessage("Got Response");
                }catch(Exception e){
                    System.out.println("checkin");
                    e.printStackTrace();                
                }

                return true;
            }
        };
    }

    public void onFooterHyperLinkClick(ActionEvent actionEvent) throws IOException, URISyntaxException {
        Desktop.getDesktop().browse(new URI(Hyperlinks.CSITEC_WEBSITE));
    }

}

在LoginController中,我有自动登录的LoginManager的对象,但每次调用loginManager.loginManager(requestMap)时都会被指定为null,我不知道为什么会这样,因为我&#39 ;我确定我的beans.xml文件正在加载,并且在该文件中我已经编写了从基础包中扫描组件的配置,并且我还在我的LoginManager类文件中编写了@Component。

这里也是LoginManager的代码:

@Component
public class LoginManager {

    @Autowired
    CommonDAO commonDAO;

    @Autowired
    JdbcTemplate jdbcTemplate1;

    public static String statusCode;
    public static String errorMessage;


    public void loginManager(Map<String, String> requestMap){
        try{

            String userName = requestMap.get(Constants.USERNAME);
            String passwordSHA = requestMap.get(Constants.PASSWORD);
            final byte[] authBytes = passwordSHA.getBytes(StandardCharsets.UTF_8);
            final String encodedPassword = Base64.getEncoder().encodeToString(authBytes);

            Object[] params = { userName, encodedPassword };
            String sqlQuery = ResourceFileReader.getSQLQuery(LookupSQLQueries.AUTHENTICATE_USER_QUERY);

            boolean result = commonDAO.validate(sqlQuery, params, jdbcTemplate1);

            if (!result) {
                errorMessage = Messages.INVALID_USERNAME_OR_PASSWORD;
                statusCode = "1";
                return;
            }

            statusCode = "0";

        }catch(Exception e){
            errorMessage = Messages.SOMETHING_WENT_WRONG;
            statusCode = "1";
        }
    }


}

请帮助我并指导我使其发挥作用。

1 个答案:

答案 0 :(得分:2)

我不是JavaFX的专家,但看起来你的对象是由JavaXF而不是Spring管理的,因此没有发生自动装配。

你需要告诉JavaXF如何处理Spring。见JavaFX and Spring - beans doesn't Autowire

public class SpringFxmlLoader {

    private static final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringApplicationConfig.class);

    public Object load(String url, String resources) {
        FXMLLoader loader = new FXMLLoader();
        loader.setControllerFactory(clazz -> applicationContext.getBean(clazz));
        loader.setLocation(getClass().getResource(url));
        loader.setResources(ResourceBundle.getBundle(resources));
        try {
            return loader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
     

重要的一行是loader.setControllerFactory(clazz -> applicationContext.getBean(clazz));

教程