Back Forum Reply New

Adding bean definitions to application context in runtime

Hello All,

I am new to spring. My question is how to add a new datasource configuration (a bean definition) at runtime without restarting the server?

My requirement.

It is is a webapplication and oUr approach is having a seperate database for each customer. But there will be a main database which has some common
information.
Suppose if a customer is added then we need to create a database for him. I am using AbstractRoutingDataSource to implement this functionality.
I implemented this by referring this ucl 2007/01...ource-routing/
This is working fine, but how can i add the datasource properties in xml file without restarting the server when a new customer is registered.
Is it possible to load the datasource dynamically without restarting the server?

FYi..I am not using hibernate or any other ORM. I am going to use only JDBCTemplate.If dynamic reloading of the context file is not possible or very complicated, what are the other ways to implement this.

My application context xml fileCode:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;!DOCTYPE beans PUBLIC quot;-//SPRING//DTD BEAN//ENquot;   quot;dtd/spring-beans.dtdquot;gt;
lt;beansgt;
lt;bean id=quot;dataSourcequot; class=quot;org..jndi.JndiObjectFactoryBeanquot;gt;
lt;property name=quot;jndiNamequot; value=quot;jdbc/SpikeDataSourcequot; /gt;
lt;property name=quot;resourceRefquot; value=quot;truequot;gt;lt;/propertygt;
lt;/beangt;
lt;bean id=quot;routingDataSourcequot; class=quot;com.spike.util.CustomerRoutingDataSource quot;gt;
lt;property name=quot;targetDataSourcesquot;gt;
lt;mapgt;
lt;entry key=quot;testquot; value-ref=quot;dataSource2quot; /gt;
lt;entry key=quot;develquot; value-ref=quot;dataSource1quot; /gt;
lt;/mapgt;
lt;/propertygt;
lt;property name=quot;defaultTargetDataSourcequot; ref=quot;dataSource1quot; /gt;
lt;/beangt;
lt;bean id=quot;dataSource1quot; class=quot;org..jdbc.datasource.DriverManagerDataSourcequot;gt;
lt;property name=quot;driverClassNamequot; value=quot;com.microsoft.sqlserver.jdbc.SQLServerDriverquot; /gt;
lt;property name=quot;uclquot; value=quot;--quot;gt;lt;/propertygt;
lt;property name=quot;usernamequot; value=quot;--quot;gt;lt;/propertygt;
lt;property name=quot;passwordquot; value=quot;---quot;gt;lt;/propertygt;
lt;/beangt;
lt;bean id=quot;dataSource2quot; class=quot;org..jdbc.datasource.DriverManagerDataSourcequot;gt;
lt;property name=quot;driverClassNamequot; value=quot;com.microsoft.sqlserver.jdbc.SQLServerDriverquot; /gt;
lt;property name=quot;uclquot; value=quot;---quot;gt;lt;/propertygt;
lt;property name=quot;usernamequot; value=quot;--quot;gt;lt;/propertygt;
lt;property name=quot;passwordquot; value=quot;---quot;gt;lt;/propertygt;
lt;/beangt;
lt;bean id=quot;jdbcTemplatequot; class=quot;org..jdbc.core.JdbcTemplatequot;gt;
lt;property name=quot;dataSourcequot; ref=quot;routingDataSourcequot;gt;lt;/propertygt;
lt;/beangt;
lt;bean id=quot;personDaoquot; class=quot;com.spike.dao.jdbc.PersonJdbcDAOquot;gt;
lt;property name=quot;jdbcTemplatequot; ref=quot;jdbcTemplatequot;gt;lt;/propertygt;
lt;/beangt;
lt;bean id=quot;spikeServicequot; class=quot;com.spike.service.impl.SpikeServiceImplquot;gt;
lt;property name=quot;personDaoquot; ref=quot;personDaoquot;gt;lt;/propertygt;
lt;/beangt;
lt;/beansgt;
I have these approaches, can we implement this,Approach 1

Can we load the xml file as file context when a user logins and store in the session for later usage? Approach 2

Stores the db propeties in a table. Read it and set it in the JNDI if already not set.
Just use JDBCTEmplates, transaction managers ourselves (without injection). Is it worth to do? Do we have any bottle necks or performance issues?

Thank you,

Regards,
Siva

Siva:

I don't know much about the routing datasource you mentioned (although it looks interesting) nor do I know if this is the best approach, but to answer the more general question about defining beans at runtime...

You can not quot;setquot; a bean on an ApplicationContext (nor a BeanFactory, to my knowledge). What I've done in the past to do something like this is to introduce a level of indirection. In other words, rather than have a datasource for each customer in the application context, you have a datasource locator bean (basically a glorified Map) that will lazily instantiate datasource beans on your behalf and return them. This isn't necessarily the cleanest method of doing this because it's difficult to then reference a datasource via the datasource locator in the property element of another bean in the context.

It sounds to me like the routing datasource you referenced is, effectively, what I'm talking about only that it has some extra functionality in that it's aware of of the application context and that it (most likely) implements the DataSource JDBC interface. Does this bean not support updates? If it does, I'd imagine the easiest thing to do is quot;listenquot; for new client events (in whatever way that makes sense in your architecture) and programmatically add a new datasource to the auto routing bean upon receipt. This allows you to not modify the application context, but the contents of a bean within it, achieving the same result.

Hope that helps and good luck.
¥
Back Forum Reply New