Spring MVC 动态数据源路由给我空指针异常

发布于 2024-10-31 21:39:59 字数 4956 浏览 0 评论 0原文

尝试遵循 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

调妓 2024-11-07 21:39:59

这是因为您自己实例化 TestDAO,而不是使用上下文中定义的 bean。您需要将 TestDAO bean 注入控制器,例如

@Controller
@RequestMapping(value="/test")
public class HandleRequest {

   private @Autowired TestDAO testDao;

   @RequestMapping(method=RequestMethod.GET)
   public String handle(Model model){    
      SessionContextHolder.setDBServer("server1");
      List domains = testDAO.getDomains();
      model.addAttribute("domains", domains);
      return "test1";
   }
}

That's because you're instantiating TestDAO yourself, and not using the bean defined in the context. You need to inject the TestDAO bean into your controller, e.g.

@Controller
@RequestMapping(value="/test")
public class HandleRequest {

   private @Autowired TestDAO testDao;

   @RequestMapping(method=RequestMethod.GET)
   public String handle(Model model){    
      SessionContextHolder.setDBServer("server1");
      List domains = testDAO.getDomains();
      model.addAttribute("domains", domains);
      return "test1";
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文