我在Spring上关注了dynamic datasource routing教程的教程。为此,我必须扩展AbstractRoutingDataSource以告诉spring要获取哪个数据源,所以我这样做:
public class CustomRouter extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
一切顺利,直到我找到负责保留customerType值的类(在整个会话期间它应该是相同的):
public class CustomerContextHolder {
private static final ThreadLocal<Integer> contextHolder = new ThreadLocal<Integer>();
public static void setCustomerType(Integer customerType) {
contextHolder.set(customerType);
}
public static Integer getCustomerType() {
return (Integer) contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
这会创建一个线程绑定的变量customerType,但是我有一个带有spring和JSF的Web应用程序我不认为有线程但有会话。所以我在登录页面中用线程 A (View)设置它,但是然后线程 B (Hibernate)请求值来知道要使用什么数据源,它是{{ 1}}确实,因为它为这个线程提供了一个新值。
有没有办法实现Session-bounded而不是Thread-bounded?
到目前为止我尝试过的事情:
null
替换为整数:不起作用,该值始终由登录的最后一位用户设置答案 0 :(得分:1)
FacesContext.getCurrentInstance()
有效吗?如果是这样,那么你可以试试这个:
public class CustomerContextHolder {
private static HttpSession getCurrentSession(){
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance()
.getExternalContext().getRequest();
return request.getSession();
}
public static void setCustomerType(Integer customerType) {
CustomerContextHolder.getCurrentSession().setAttribute("userType", customerType);
}
public static Integer getCustomerType() {
return (Integer) CustomerContextHolder.getCurrentSession().getAttribute("userType");
}
public static void clearCustomerType() {
contextHolder.remove(); // You may want to remove the attribute in session, dunno
}
}