Como mudar as configurações do Spring com o sistema rodando?

0 respostas
P

Olá pessoal, estou desenvolvendo uma aplicação com spring+hibernate+jsf no qual para fazer transação com o banco de dados, injeto um bean que contém toda a configuração de um datasource, o problema é que eu quero mudar essa configuração de banco de dados(username,password,driver,url) em tempo de execução para se conectar com um outro banco, mais o spring não aceita.

Estou tentado mudar a configuração do banco de acordo com o nome de login que pertence ao contexto atual.

O sistema pega esse login e verifica em um banco temporário se esse login contém algum servidor sendo gerenciado, se tem ele pega os dados para se conectar com outro banco.

O problema é que antes de autenticar, por que também estou utilizando o spring-security, ainda não existe nenhum login no contexto atual, e o sistema nem inicia por que ele precisa dessas informações.

Dá um erro de nulo.

agradeço por qualquer respota.

pra melhorar a ajuda vou postar o codigo.

Tenho o seguinte arquivo do spring:

spring-config  
      
    <?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"   
                xmlns:sec="http://www.springframework.org/schema/security"  
           xmlns:tx="http://www.springframework.org/schema/tx"  
           xsi:schemaLocation="http://www.springframework.org/schema/beans   
               [url]http://www.springframework.org/schema/beans/spring-beans-3.0.xsd[/url]   
               [url]http://www.springframework.org/schema/security[/url]   
               [url]http://www.springframework.org/schema/security/spring-security-3.0.xsd[/url]   
               [url]http://www.springframework.org/schema/context[/url]   
               [url]http://www.springframework.org/schema/context/spring-context-3.0.xsd">[/url]  
             
            <!-- Parâmetros de conexão com o banco de dados -->  
       <bean id="dataSourcePostgre" class="br.com.vicente.config.conexao.Conexao"/>  
      
             <!--configuração postgre-->  
             <bean id="daoGenericoCliente" class="br.com.vicente.util.DaoGenericoCliente">  
             <property name="sessionFactory" ref="sessionFactory2" />      
             </bean>  
               
           <bean id="sessionFactory2"  
               class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
               <property name="dataSource" ref="dataSourcePostgre" />  
               <property name="annotatedClasses">  
                   <list>  
                            <value>br.com.vicente.model.Dialplan</value>  
                            <value>br.com.vicente.model.Chamada</value>  
                   </list>  
               </property>  
                    <!--propriedade do hibernate-->  
               <property name="hibernateProperties">  
                   <props>  
                       <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>  
                       <prop key="hibernate.show_sql">true</prop>  
                       <prop key="hibernate.hbm2ddl.auto">update</prop>  
                   </props>  
               </property>  
           </bean>  
                  
                <!-- View scope, recupera o scopo -->  
           <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">  
               <property name="scopes">  
                   <map>  
                       <entry key="view">  
                           <bean class="br.com.vicente.util.ViewScope"/>  
                       </entry>  
                   </map>  
               </property>  
           </bean>  
       </beans>

Tenho a seguinte classe de conexão:

package br.com.vicente.config.conexao;  
      
    import br.com.vicente.managerBean.config_serializableBean;  
    import java.util.Properties;  
    import org.springframework.jdbc.datasource.DriverManagerDataSource;  
      
      
    public class Conexao extends DriverManagerDataSource{  
    //informações de conexao com o banco valores default  
      
    Properties properties;  
    config_serializableBean obj_leitura;  
      
    public Conexao() {  
    le_conf();  
    }  
      
    //ler as configurações de um arquivo de propriedades  
    private void le_conf() {  
    obj_leitura = new config_serializableBean();  
    properties = new Properties();  
    properties = obj_leitura.loadProperties();  
      
    Object driver_temp = properties.getProperty("jdbc.driverClassName");  
    Object username_temp = properties.getProperty("jdbc.username");  
    Object password_temp = properties.getProperty("jdbc.password");  
    Object banco_temp = properties.getProperty("banco");  
    Object ip_temp = properties.getProperty("ip");  
    Object porta_temp = properties.getProperty("porta");  
    Object bancoDados_temp = properties.getProperty("bancoDados");  
      
    String url_temp = "jdbc:"+banco_temp.toString()+"://"+ip_temp.toString()+":"+porta_temp.toString()+"/"+bancoDados_temp.toString();  
      
    this.setDriverClassName(driver_temp.toString());  
    this.setUrl(url_temp);  
    this.setUsername(username_temp.toString());  
    this.setPassword(password_temp.toString());  
    }  
    }

Classe para pegar as configurações de um arquivo de propriedade:

package br.com.vicente.managerBean;  
      
    import br.com.vicente.model.config_serializable;  
    import java.io.FileInputStream;  
    import java.io.FileOutputStream;  
    import java.io.IOException;  
    import java.io.Serializable;  
    import java.util.Properties;  
    import java.util.Set;  
    import javax.faces.bean.ManagedBean;  
    import javax.faces.bean.SessionScoped;  
    import javax.faces.context.FacesContext;  
      
    /** 
    * 
    * @author Vicente 
    */  
    @ManagedBean  
    @SessionScoped  
    public class config_serializableBean implements Serializable{  
      
    private String login_temp;  
    private Properties table;  
    private config_serializable obj_leitura = new config_serializable();  
    private config_serializable obj_conf = new config_serializable();  
      
    public config_serializableBean() {  
    }  
      
    public config_serializableBean(Properties table){  
    this.table=table;  
    }  
      
    // salva as propriedades em um arquivo  
    public void saveProperties()  
    {  
    FacesContext fc = FacesContext.getCurrentInstance();  
    //pega o nome do usuario atual  
    login_temp = fc.getExternalContext().getUserPrincipal().getName();  
    try  
    {  
    FileOutputStream output = new FileOutputStream("C:/configuracoes/conf"+login_temp+".properties");  
    table.store( output, "Sample Properties" );// salva as propriedades  
    output.close(); // fecha o arquivo  
    }  
    catch ( IOException ioException )  
    {  
    ioException.printStackTrace();  
    }  
    }  
      
    //faz a leitura do arquivo properties  
    public Properties loadProperties()  
    {  
    // carrega o conte?do de tabela  
    Set&lt;Object&gt; keys=null;  
    FacesContext fc = FacesContext.getCurrentInstance();  
    //pega o nome do usuario atual  
    login_temp = fc.getExternalContext().getUserPrincipal().getName();  
    try  
    {  
    FileInputStream input = new FileInputStream( "C:/configuracoes/conf"+login_temp+".properties" );  
    table.load(input);// carrega propriedades  
    input.close(); // fecha o arquivo  
    //listProperties(); // exibe os valores da propriedade  
    }catch ( IOException ioException )  
    {  
    ioException.printStackTrace();  
    }  
    return table;  
    }  
      
    //gera sa?da de valores de propriedade  
    public Set&lt;Object&gt; listProperties()  
    {  
    Set&lt;Object&gt; keys = table.keySet(); // obtem nomes de propriedade  
    return keys;  
    }  
      
      
    public void limpar_properties() {  
    FacesContext fc = FacesContext.getCurrentInstance();  
    login_temp = fc.getExternalContext().getUserPrincipal().getName();  
    try {  
    table=new Properties();  
    FileOutputStream output = new FileOutputStream("C:/configuracoes/conf"+login_temp+".properties");  
    table.store( output, "Sample Properties" );// salva as propriedades  
    output.close();  
    } catch (Exception erro_grava) {  
    }  
    }  
    }
O seguinte Bean gerenciavel:

    package br.com.vicente.managerBean;  
      
    import br.com.vicente.model.Dialplan;  
    import java.io.Serializable;  
    import org.springframework.beans.factory.annotation.Autowired;  
    import org.springframework.context.annotation.Scope;  
    import org.springframework.stereotype.Controller;  
      
    /** 
    * 
    * @author Vicente 
    */  
    @Controller("dialplanBean")  
    @Scope("view")  
    public class dialplanBean implements Serializable{  
    public Dialplan dialplan = new Dialplan();  
      
    @Autowired  
    public dialplanBean(DaoGenericoCliente daoGenericoCliente) {  
    this.daoGenericoCliente = daoGenericoCliente;  
    }  
      
    //apartir daqui utilizo o objeto daoGenericoCliente para salvar, deletar, atualizar e pesquisar  
      
    }

Quando o sistema inicializa o arquivo spring-config é carregado e procura pela classe de conexão para pegar os dados
de conexão. Através do login que é o nome que está no contexto atual, ele procura por um arquivo chamado nomedologin.properties.
Mas quando a aplicação ainda está iniciando ele tenta carregar essas informações mas esse nome de login ainda é nulo, então dá um erro e o sistema não chega nem a iniciar.

Eu preciso modificar a configuração enquanto o sistema estiver rodando pra me conectar com outros servidores.

Da forma que está, só posso me conectar com um banco só e esse é o problema.

Toda vez que precisar gerenciar outro banco é necessario parar o servidor e modificar as configurações na mão pra funcionar, tornando a aplicação totalmente inviavel.

Já tentei fazer o seguinte ao invés de carregar o spring-config na inicialização,
coloco esse arquivo em um pacote junto com as classes java, fora da inicialização que estáva no arquivo web.xml.

E pego o bean através da seguinte classe:

package br.com.vicente.config.conexao;  
      
      
    import org.springframework.context.support.ClassPathXmlApplicationContext;  
      
    /* 
    * Lê o arquivo de configuração do spring (spring.xml) e fornece métodos para recuperar os beans declarados no arquivo de configuração do spring 
    */  
    public class BeanFactory {  
      
    public ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("br/com/vicente/config/conexao/spring-config.xml");  
      
    public Object getBean(String beanName) {  
    return ctx.getBean(beanName);  
    }  
      
    public Object getBean(String beanName, Class classe) {  
    return ctx.getBean(beanName, classe);  
    }  
      
    }  
      
      
    e na classe que vou fazer as operações com o banco de dados faço o seguinte:  
      
    daoGenericoCliente = (DaoGenericoCliente) new BeanFactory().getBean("daoGenericoCliente");  
      
    public void insere() {  
    daoGenericoCliente.insere(obj);  
    }  
      
      
    public void excluir() {  
    daoGenericoCliente.exluir(obj);  
    }  
      
      
    public void atualiza(){  
    daoGenericoCliente.atualiza(obj);  
    }

Dessa forma funciona porque o arquivo é carregado depois de iniciado, pois já tenho um login no contexto atual e ele não é mais nulo.

Mas toda vez que precisar fazer uma transação com o banco esse arquivo terá que ser carregado, deixando a aplicação muito lenta.

Mais muito lenta mesmo… não vale a pena.

O que preciso é conseguir alguma outra solução na forma anterior.

Bom pessoal, se alguém poder me ajudar serei muito agradecido.

Já faz muito tempo que ando pesquisando na internet, livros, apostilas, e não encontrei nada.

Será que alguém nunca precisou modificar as configurações de conexão do spring com o sistema rodando.

Criado 19 de maio de 2012
Respostas 0
Participantes 1