在JavaFX + Spring Boot + Hibernate应用程序中支持多种环境

时间:2020-01-08 10:49:09

标签: java spring hibernate spring-boot javafx

我正在使用hibernate在Spring Boot中构建JavaFX应用程序。它连接到数据库以显示一些数据,当前它从属性文件获取连接详细信息,并使用纯Java配置加载sessionFactory,数据源和事务管理器bean。但是,我有多个数据库位于多个远程计算机上,每个数据库都有不同的IP和用户详细信息。理想情况下,我想显示一个登录表单,该表单在应用程序启动时提示输入db用户名和密码。我不想从文件中读取这些详细信息。有可能吗对于这个问题,我将不胜感激。

编辑: 通过实现这一目标,在我的登录控制器中,我只需实现ApplicationContextAware,然后使用文本字段中的数据手动加载注册bean。

2 个答案:

答案 0 :(得分:1)

您可以使用Spring Boot Active Profile features

根据您当前的概要文件PROD,DEV,PRE-PROD,您可以使用给定的application.properties文件激活特定的配置。您可以在此处找到完整的How to

编辑2:

如果要基于用户输入(例如,其凭据)更改整个配置,则必须动态更改属性,并且看来@RefreshScope可以完成工作。

坏消息是此注释似乎仅存在于Spring Cloud

答案 1 :(得分:0)

这是我的解决方案,唯一的缺点是登录尝试失败后我无法登录。它工作正常,但是如果我先使用不正确的登录凭据,然后再使用正确的登录凭据,则会抛出异常,表明EntityManagerFactory已关闭。 (我确实在我的catch块中删除了bean定义,只是想使代码更短)

@Component
public class LoginController implements Initializable, ApplicationContextAware{

    @FXML
    private AnchorPane login;
    @FXML
    private JFXTextField dbUsernameTextField;
    @FXML
    private JFXPasswordField dbPasswordTextField;
    @FXML
    private JFXTextField boxUsernameTextField;
    @FXML
    private JFXPasswordField boxPasswordTextField;
    @FXML
    private JFXComboBox<ComboItem> environmentComboBox;
    @FXML
    private JFXButton loginButton;
    @Autowired 
    private Environment environment;

    @Autowired
    private OrderService orderService;

    private AnnotationConfigApplicationContext context;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        loginButton.setDisable(true);
        List<ComboItem> envs=new ArrayList<ComboItem>();
        String[]environments=environment.getProperty("environments").split(",");
        for(String s:environments) {
            environmentComboBox.getItems().add(new ComboItem(s.toUpperCase(),s));
        }
        environmentComboBox.setConverter(new StringConverter<ComboItem>() {
            @Override
            public String toString(ComboItem object) {
                return object.getKey();
            }
            @Override
            public ComboItem fromString(String string) {
                return null;
            }
        });
    }

    @FXML
    public void selectEnvironment() {
        if(!environmentComboBox.getSelectionModel().isEmpty())
            loginButton.setDisable(false);
    }

    @FXML
    public void authenticate(ActionEvent actionEvent) {

        String boxUsername=boxUsernameTextField.getText();
        String boxPassword=boxPasswordTextField.getText();
        try {
            context.registerBean("dataSource",DataSource.class,()->dataSource());
            context.registerBean("sessionFactory", LocalSessionFactoryBean.class,()->sessionFactory());     
            context.registerBean("transactionManager",HibernateTransactionManager.class,()->getTransactionManager());

            Order order=orderService.findById("");

            FXMLLoader fxmlLoader=new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
            fxmlLoader.setControllerFactory(context::getBean);
            Parent rootNode=fxmlLoader.load();
            Stage stage=(Stage) login.getScene().getWindow();
            Scene scene=new Scene(rootNode,400,300);
            stage.setScene(scene);
            stage.setTitle("Login");
            stage.setMaximized(true);
            stage.show();
            stage.setOnCloseRequest(event->JSchConnection.close());
        }catch(Exception e) {
        context.removeBeanDefinition("dataSource");
        context.removeBeanDefinition("sessionFactory");
        context.removeBeanDefinition("transactionManager");

            e.printStackTrace();
        }

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context=(AnnotationConfigApplicationContext) applicationContext;       
    }

    private  Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
        properties.put("hibernate.show_sql", "false");
        properties.put("hibernate.format_sql", "true");
        properties.put("hibernate.hbm2ddl.auto", "none");
        return properties;
    }

    public  DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
        dataSource.setUrl("myurl");
        dataSource.setUsername(dbUsernameTextField.getText());
        dataSource.setPassword(dbPasswordTextField.getText());
        return dataSource;
    }

    public  LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "com.mypackage" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    public HibernateTransactionManager getTransactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(context.getBean(SessionFactory.class,"sessionFactory"));
        return transactionManager;
    }

}