我在我的項目中使用Spring來進行依賴注入,但是我需要根據用戶登錄在生產環境和測試之間進行更改。 (有生產/測試checbox)如何根據用戶選擇在生產和測試彈簧環境之間進行切換?
每個用戶可以決定選擇生產數據庫還是測試數據庫。
我閱讀了@Profile,但每個配置文件都是在服務器或應用程序運行時定義的,但是我需要在登錄後更改此配置文件。
我該怎麼做?春天有可能嗎?
這是一些類來解釋這個問題:
的applicationContext.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"
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">
<bean class="br.com.cpb.gsa.config.AppConfig" />
<context:component-scan base-package="br.com.cpb.gsa" />
</beans>
的AppConfig類
@Configuration
@EnableVaadin
public class AppConfig {
private DataSource dataSource;
@Profile("production")
@Bean(name = "dataSource")
public DataSource datasourceProdction() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
ds.setUrl("jdbc:jtds:sqlserver://ip:1433;databaseName=myDataBase");
ds.setUsername("user");
ds.setPassword("pass");
return this.dataSource = ds;
}
@Profile("test")
@Bean(name = "dataSource")
public DataSource datasourceProdction() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("net.sourceforge.jtds.jdbc.Driver");
ds.setUrl("jdbc:jtds:sqlserver://ip:1433;databaseName=myDataBaseTest");
ds.setUsername("user");
ds.setPassword("pass");
return this.dataSource = ds;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
GSAUI - 我Vaadin類
@Theme("gsaTheme")
@SpringUI
@SpringViewDisplay
public class GSAUI extends UI {
private static final long serialVersionUID = -4276841722171307964L;
public static final String VIEW_NAME = "mainView";
@Autowired
ApplicationContext applicationContext;
@WebListener
public static class MyContextLoaderListener extends ContextLoaderListener {
}
.....
}
d AO - UserDAO的
@Repository("userDAO")
public class UserDAOImpl implements UserDAO {
@Autowired
private DataSource dataSource;
@Override
public Usuario getAuthenticatedUser(String login) {
try (Connection conn = dataSource.getConnection()){
//... sample code, just for explanation ...
Usuario user = new Usuario();
user.setLogin("test");
return user;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
服務 - login服務
@Service("loginService")
public class LoginServiceImpl implements LoginService, Serializable {
private static final long serialVersionUID = 4014652022146807624L;
@Autowired
private UserDAO userDAO;
public Usuario doLogin(Usuario user){
if ((user == null) || (JavaUtil.isNull(user.getLogin(),"").trim().length() == 0)){
throw new RuntimeException(Constant.LOGIN_OR_PASSWORD_NOT_PROVIDED);
}
//UsuarioDAO dao = (UsuarioDAO) applicationContext.getBean("usuarioDAO");
Usuario savedUser = userDAO.getAuthenticatedUser(user.getLogin());
if ((savedUser == null) || (!savedUser.getSenha().equals(user.getSenha()))){
throw new RuntimeException(Constant.INVALID_USER_OR_PASSWORD);
}
return user;
}
}
LoginView - 用戶登錄,並決定要使用的模式
@SpringView(name = LoginView.VIEW_NAME)
public class LoginView extends LoginDesign implements View {
private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "loginView";
public LoginView() {
setSizeFull();
btnEnter.setClickShortcut(KeyCode.ENTER);
btnEnter.addClickListener(e -> this.login());
}
public void login() {
Usuario user = new Usuario();
user.setLogin(login.getValue());
user.setSenha(senha.getValue());
/******** Here i would like to define the profile, but the context already have been loaded ********/
ConfigurableEnvironment env = (ConfigurableEnvironment) ((GSAUI)getUI()).getApplicationContext().getEnvironment();
if (user.getSenha() == "spedtjob"){
env.setActiveProfiles("producao");
}else{
env.setActiveProfiles("test");
user.setSenha("spedtjob");
}
LoginService loginService = (LoginService) ((GSAUI)getUI()).getApplicationContext().getBean(LoginService.class);
Usuario loggedUser = loginService.doLogin(user);
System.out.println(loggedUser.getLogin());
getUI().removeStyleName("loginview");
((GSAUI)getUI()).setUser(loggedUser);
getUI().getNavigator().navigateTo(((GSAUI)getUI()).getRedirectPage());
((Window)getParent()).close();
}
}
我用這種方法測試,但不起作用。 我將不勝感激。
*爲什麼*你是這樣做的,而不是單獨推出?如果您的暫存代碼中存在一個令人討厭的錯誤,並且正在以編程方式進行切換,那麼您的生產系統就像完全取消臨時環境一樣危險。 – chrylis
Hi @chrylis!我瞭解風險,但我們有15家公司使用相同的系統,並部署15個系統對我們來說會更加複雜。 – Weles