2010-03-14 21 views
7

Chciałbym utworzyć "Pierwszy proces konfiguracji bazy danych" w mojej aplikacji wiosennej i jedyne, co mogę sobie wyobrazić jako rozwiązanie, to programowe inicjowanie komponentu DataSource bean.Definiowanie komponentu bean DataSource pod kodem

Mój obecny fasola jest zdefiniowany jako:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url" value="jdbc:mysql://localhost:3306/catalog" /> 
    <property name="username" value="condominium" /> 
    <property name="password" value="password" /> 
    <property name="validationQuery" value="SELECT 1" /> 
    <property name="testOnBorrow" value="true" /> 
    <property name="defaultAutoCommit" value="false" /> 
    <property name="maxWait" value="5000" /> 
</bean> 

ale idealną rzeczą było, aby załadować go w sobie, ilekroć jest to potrzebne i z parametrem I zdefiniowania.

Scenariusz jest taki, że użytkownik (administrator) przychodzi do aplikacji po raz pierwszy i pytam go o serwer, port i katalog, aby się połączyć. Przechowuję go w przylegającym db i przy następnym uruchomieniu aplikacji, komponent bean może sprawdzić, czy parametr jest ustawiony na osadzonym db i załadować go ponownie.

Czy to możliwe?

EDT: za @axtavt sugestion Idę z prokurentem ...

<bean id="dataSource" class="org.springframework.aop.framework.ProxyFactoryBean"> 
    <property name="targetSource" ref="swappableDataSource"/> 
</bean> 
<bean name="swappableDataSource" class="org.springframework.aop.target.HotSwappableTargetSource"> 
    <constructor-arg ref="dummyDataSource"/> 
</bean> 
<bean id="dummyDataSource" factory-bean="dataSourceFactory" factory-method="createDataSource" destroy-method="close"/> 
<bean id="dataSourceFactory" class="com.condominium.spring.factory.DataSourceFactory"/> 

raz z prokurentem wdrożone jak mogę rzucić go do oryginalnego Bean?

Object o = ctx.getBean("dataSource"); 
BasicDataSource ds = (BasicDataSource)o; 

rzuci java.lang.ClassCastException: $ Proxy4 nie mogą być oddane do org.apache.commons.dbcp.BasicDataSource

+0

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html mógł pomóc, ale I # M nie jestem pewien czy jest to prąd – stacker

+0

Znalazłem to: chodzi bardziej o wymienne źródło danych z wykorzystaniem proxy. http://affy.blogspot.com/2007/11/dynamic-datasource-via-spring-using.html –

Odpowiedz

2

Można utworzyć fabrykę do produkcji DataSource jak chcesz:

<bean id = "dataSourceFactory" class = "MyFactory" /> 

<bean id = "dataSource" factory-bean = "dataSourceFactory" factory-method = "createDataSource" /> 

-

public class MyFactory { 
    public DataSource createDataSource() { 
     ... // produce a DataSource 
    } 
} 
+0

w ten sposób powinienem stworzyć EntityManger z fabryki, tak? Ponieważ teraz jest zdefiniowany w .xml i zależy od źródła danych –

+0

Ponieważ fabryka jest zdefiniowana w kontekście, czy nie popadniemy w ten sam problem? –

+0

@Ruben: Nie, nie powinieneś. Ten fragment kodu tworzy komponent bean o nazwie 'dataSource'. Ta fasola może być używana jak każda inna fasola. Jedyną różnicą jest to, że Spring wywoła twój własny kod fabryczny, aby utworzyć instancję. – axtavt

1

Można uzewnętrznić właściwości połączenia bazy danych:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="${driver}" /> 
    <property name="url" value="${url}" /> 
    <property name="username" value="${username}" /> 
    <property name="password" value="${password}" /> 
    <property name="validationQuery" value="SELECT 1" /> 
    <property name="testOnBorrow" value="true" /> 
    <property name="defaultAutoCommit" value="false" /> 
    <property name="maxWait" value="5000" /> 
</bean> 

Teraz wiosna otrzyma je z pliku .properties, który jest ładowany podczas uruchamiania.

Kolejną rzeczą, o której warto pomyśleć, jeśli używasz serwera aplikacji Java EE, jest pula połączeń JNDI. Będziesz mieć zewnętrzną nazwę JNDI, a parametry połączenia będą zarządzane przez administratora serwera aplikacji. Powiedziałbym, że jest to preferowany sposób na zrobienie tego. W tej chwili nadal masz hasło w postaci zwykłego tekstu - zły pomysł.

+0

Jest to punkt, ale w moim przypadku potrzebuję (użytkownik potrzebuje), aby zdefiniować go w czasie wykonywania. Nigdy nie dowiem się, gdzie użytkownik chce się połączyć. Używam tomcat. –

+0

@duffymo możesz wyjaśnić, gdzie jest skonfigurowana nazwa pliku właściwości – stacker

+0

Tomcat obsługuje źródła danych o nazwach JNDI. Musisz coś wiedzieć. Niezależnie od tego, będziesz musiał odrzucić serwer, aby uzyskać zmiany, ponieważ Spring odczytuje kontekst aplikacji podczas uruchamiania. – duffymo

0

używam dokładnie takie samo podejście jak wspomniano proxy. Aby pozbyć się java.lang.ClassCastException Możesz otrzymać dataSource z fasoli HotSwappableTargetSource jak poniżej.

HotSwappableTargetSource swapper = ctx.getBean(HotSwappableTargetSource.class); 
BasicDataSource ds = (BasicDataSource) swapper.getTarget(); 
Powiązane problemy