Reputation: 3064
Suppose I have a couple different datasources defined as spring beans:
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/db1?user=root&password=password" />
</bean>
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/db2?user=root&password=password" />
</bean>
Now I'd like to use one of these datasource beans but from a non-spring bean container. I could call appContext.getBean("dataSource1") but I've read that's bad practice since it creates an explicit dependency on the spring framework in your code. Is there are better way to accomplish this in a way that is not implementation specific? Perhaps something like DatasourceFactory.getInstance("datasource1")?
Is this a weird request? I realize this would be very easy if the container class was a Spring bean since I could just use standard dependency injection in that case. But this is something I've been curious about. It seems that using dependency injection creates an endless loop, where if you want to use a spring bean in a class then that class must also be a bean, and then if another class wants to use that bean then it must also be a bean, and so on, and so on. I don't see an elegant way to break the dependency injection chain.
Again, maybe it's not necessary to break the chain, maybe the answer is that you do make all your classes spring beans, but I was just curious.
Can service locator pattern be applied here? If so can someone provide an example? Thanks.
Upvotes: 0
Views: 1282
Reputation: 280172
The method you describe is the classic way to do it.
public class UnmanagedBean {
public UnmanagedBean(DataSource dataSource) {
... // do something
}
}
...
ApplicationContext context = ...;
DataSource dataSource2 = context.getBean("dataSource2");
UnmanagedBean bean = new UnmanagedBean(dataSource2);
You can add a level of abstraction with a BeanProvider
class that does this for you, but you are limited to getting the beans directly from the ApplicationContext
.
Upvotes: 1