Spring MVC 动态数据源路由给我空指针异常
尝试遵循 http://blog.springsource.com/ 上的代码2007/01/23/动态数据源路由/ 但出现令人讨厌的空指针异常:
//DAO
public class TestDAO extends SimpleJdbcDaoSupport {
public List<Map> getDomains() {
String query = "select 1 from dual";
return getSimpleJdbcTemplate().queryForList(query);
}
}
//Routing
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return SessionContextHolder.getDBServer();
}
}
//controller
@Controller
@RequestMapping(value="/test")
public class HandleRequest {
@RequestMapping(method=RequestMethod.GET)
public String handle(Model model){
TestDAO testDAO = new TestDAO();
SessionContextHolder.setDBServer("server1");
List domains = testDAO.getDomains();
model.addAttribute("domains", domains);
return "test1";
}
}
my beans
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="springtest" />
<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
<bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" abstract="true">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="" />
<property name="password" value="" />
<property name="initialSize" value="5"/>
<property name="validationQuery" value="select 1" />
<property name="defaultAutoCommit" value="false" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="10" />
<property name="maxWait" value="15000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="300" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="master" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.master}/te_admin?autoReconnect=true" />
</bean>
<bean id="server1" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.server1}/te_db?autoReconnect=true"/>
</bean>
<bean id="server2" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.server2}/te_db?autoReconnect=true"/>
</bean>
<bean id="server3" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.server3}/te_db?autoReconnect=true"/>
</bean>
<bean id="masterJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg><ref bean="master"/></constructor-arg>
</bean>
<bean id="testdao" class="springtest.TestDAO">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="springtest.RoutingDataSource">
<property name="targetDataSources">
<map>
<entry key="server1" value-ref="server1"/>
<entry key="server2" value-ref="server2"/>
<entry key="server3" value-ref="server3"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="server3"/>
</bean>
<!-- properties file -->
<context:property-placeholder location="classpath:local.properties"/>
</beans>
这就是错误
java.lang.NullPointerException
springtest.TestDAO.getDomains(TestDAO.java:15)
Trying to follow the code at http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/
but getting a nasty null pointer exception:
//DAO
public class TestDAO extends SimpleJdbcDaoSupport {
public List<Map> getDomains() {
String query = "select 1 from dual";
return getSimpleJdbcTemplate().queryForList(query);
}
}
//Routing
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return SessionContextHolder.getDBServer();
}
}
//controller
@Controller
@RequestMapping(value="/test")
public class HandleRequest {
@RequestMapping(method=RequestMethod.GET)
public String handle(Model model){
TestDAO testDAO = new TestDAO();
SessionContextHolder.setDBServer("server1");
List domains = testDAO.getDomains();
model.addAttribute("domains", domains);
return "test1";
}
}
my beans
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="springtest" />
<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
<bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" abstract="true">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="" />
<property name="password" value="" />
<property name="initialSize" value="5"/>
<property name="validationQuery" value="select 1" />
<property name="defaultAutoCommit" value="false" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="10" />
<property name="maxWait" value="15000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="300" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="master" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.master}/te_admin?autoReconnect=true" />
</bean>
<bean id="server1" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.server1}/te_db?autoReconnect=true"/>
</bean>
<bean id="server2" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.server2}/te_db?autoReconnect=true"/>
</bean>
<bean id="server3" parent="parentDataSource">
<property name="url" value="jdbc:mysql://${db.host.server3}/te_db?autoReconnect=true"/>
</bean>
<bean id="masterJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg><ref bean="master"/></constructor-arg>
</bean>
<bean id="testdao" class="springtest.TestDAO">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="springtest.RoutingDataSource">
<property name="targetDataSources">
<map>
<entry key="server1" value-ref="server1"/>
<entry key="server2" value-ref="server2"/>
<entry key="server3" value-ref="server3"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="server3"/>
</bean>
<!-- properties file -->
<context:property-placeholder location="classpath:local.properties"/>
</beans>
And this is the error
java.lang.NullPointerException
springtest.TestDAO.getDomains(TestDAO.java:15)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为您自己实例化
TestDAO
,而不是使用上下文中定义的 bean。您需要将 TestDAO bean 注入控制器,例如That's because you're instantiating
TestDAO
yourself, and not using the bean defined in the context. You need to inject theTestDAO
bean into your controller, e.g.