我看了this post,但我不明白如何使用ThreadLocal
或DataSourceLookup
或AbstractRoutingDataSource
访问请求。我阅读了每篇文章,但它仍然无效。
如何访问我的请求的dataSource
参数并动态创建与他们的连接?
答案 0 :(得分:1)
我认为这就像你联系到的答案一样:
警告:这些都没有编译过。这些都没有经过测试。
每个请求运行一次CurrentRequestFilter
。它负责将当前请求存储在稍后将使用的ThreadLocal
中。
public class CurrentRequestFilter extends OncePerRequestFilter {
private ThreadLocal<HttpServletRequest> currentRequest;
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
currentRequest.set(request);
filterChain.doFilter(request, response);
}
public ThreadLocal<HttpServletRequest> getCurrentRequest() {
return currentRequest;
}
public void setCurrentRequest(ThreadLocal<HttpServletRequest> currentRequest) {
this.currentRequest = currentRequest;
}
}
CurrentRequestDataSource
可以访问与ThreadLocal
相同的CurrentRequestFilter
。
public class CurrentRequestDataSource extends AbstractRoutingDataSource {
private ThreadLocal<HttpServletRequest> currentRequest;
@Override
protected DataSource determineTargetDataSource() {
HttpServletRequest request = currentRequest.get();
String url = ...;
String username = ...;
String password = ...;
DataSource dataSource = ...;
return dataSource;
}
@Override
protected Object determineCurrentLookupKey() {
return null;
}
public ThreadLocal<HttpServletRequest> getCurrentRequest() {
return currentRequest;
}
public void setCurrentRequest(ThreadLocal<HttpServletRequest> currentRequest) {
this.currentRequest = currentRequest;
}
}
然后,您将配置您的bean定义:
<bean id="currentRequest" class="java.lang.ThreadLocal"/>
<bean id="currentRequestFilter" class="CurrentRequestFilter">
<property name="currentRequest" ref="currentRequest"/>
</bean>
<bean id="dataSource" class="CurrentRequestDataSource">
<property name="currentRequest" ref="currentRequest"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
然后,您必须确保在CurrentRequestFilter
文件中注册了web.xml
:
<filter>
<filter-name>Current Request Filter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>currentRequestFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Current Request Filter</filter-name>
<servlet-name>Name_Of_Your_Servlet</servlet-name>
</filter-mapping>
同样,这些都没有经过测试,但希望它可以提供一些指导。
答案 1 :(得分:0)
我不确定您的意思是什么,或者请求是什么。你想写一个网络应用程序吗?这是一个HttpRequest吗?您是否根据请求确定了所需的数据源?
根据这些问题的答案,您可能不需要动态访问数据源。
如果您有多个数据源,每个数据源都提供不同类型的请求,我建议将数据源注入服务对象,这些对象会注入到为特定URL选择的Web控制器中。您将能够以这种方式改变数据源,并且没有什么比Web层中的URL映射更有趣。
在不了解您的用例的情况下,我猜你已经过度复杂了,因为你是Spring的新手并且还不知道如何正确使用它。没有任何侮辱,只是猜测。
更新:
“我无法改变它” - 在假设之前,你至少应该与客户讨论它。这是一个坏主意。加密参数不会保存您。
您最好创建一个工厂,Controller可以使用它来实例化注入了您需要的所有数据源的工厂。将数据源存储在地图中,只需来回传递一个密钥即可获取数据源。 Controller已经可以访问请求;保护用户不必知道有关数据库的所有细节;你使查找成为一个简单的密钥(我仍然不喜欢)。
如果看起来太难了,你可能不应该这样做。有更简单的方法。反思它。