Spring注入的DataSource为空

Posted

技术标签:

【中文标题】Spring注入的DataSource为空【英文标题】:Spring injected DataSource is null 【发布时间】:2016-04-03 21:13:55 【问题描述】:

我正在尝试使用 JdbcTemplate 制作 DAO。但似乎 Spring 注入并不顺利。我正在使用 Tomcat 的 JNDI 注入 DataSource。

我还在 Tomcats server.xml 中编写了设置,在 /META-INF 中编写了 ResourceLink,在 web.xml 中编写了资源引用,尝试在 web.xml 中添加上下文侦听器,它也没有帮助(实际上,我应该添加侦听器,如果我不是从 servlet 访问 DataSource,而只是从 DAO 访问?)。

我错过了什么,为什么 Spring 不注入它?

dao-context.xml

 <context:component-scan base-package="somepackage"/>
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/phonebook" expected-type="javax.sql.DataSource"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

web.xml

 <resource-ref>
    <description>DatasourceJNDI</description>
    <res-ref-name>jdbc/phonebook</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

META-INF/context.xml

<Context>
<ResourceLink name="jdbc/phonebook" global="jdbc/global_phonebook" type="javax.sql.DataSource"/>

Tomcat 中的 server.xml

<Resource name="jdbc/global_phonebook" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/phonebook" username="root" password="1234" maxActive="10" maxIdle="5" maxWait="-1" defaultAutoCommit="false" defaultTransactionIsolation="READ_COMMITTED"/>

tomcat 本地主机日志 http://shorttext.com/700e4579 tomcat catalina 日志 http://shorttext.com/700f24cb

【问题讨论】:

我假设,您在日志中没有异常,找不到数据源,所以我会说问题出在您的注入上?你是如何创建 DAO 的,请分享一下配置。 我在第 168 行有 NullPointerException。这一行有 jdbcTemplate.getDataSource() 方法。打印的 dataSource 变量,它说它是“null”,就像 jdbcTemplate 一样。所以我假设没有注入 JNDI。使用 Autowired 注解注入并使用 Repository 注解定义的 DAO。使用 在 context.xml 中扫描。 DAOs 注入工作。使用上下文配置更新问题。 你能发布堆栈跟踪吗? 当然。 *** 不允许粘贴,添加了有问题的 txt 的链接 【参考方案1】:

与我的工作示例相比,我能看到的唯一区别是,我在 Tomcat 的 context.xml 中使用了这个:

<Resource name="jdbc/MySQL"
            auth="Container"
            type="javax.sql.DataSource"
            username="root"
            password=""
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/so"
            maxActive="8"
            maxIdle="4"/>

我使用 Tomcat 7.0.47 对此进行了测试,并遵循了此文档 - https://tomcat.apache.org/tomcat-7.0-doc/jndi-resources-howto.html

编辑:

我又看了你的评论,如果

jdbcTemplate.getDataSource()

抛出 NPE,则 jdbcTemplate 必须为空。你能分享你的 DAO 代码吗?


嗨,米莎,抱歉回答晚了。

我创建了非常简单的控制器来测试:

@Controller
public class ExecuteController 

    @Autowired
    JdbcTemplate jdbcTemplate;

    @ResponseBody
    @RequestMapping(path="execute")
    public String execute() 
        return new Date().toString() + ": executed " + (jdbcTemplate == null);
    


当我执行它时,我得到了

Wed Jan 06 09:22:59 CET 2016: executed false

false 表示它不为空。

我有空的根上下文和 servlet 上下文是:

<?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:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="test" />

    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/MySQL" expected-type="javax.sql.DataSource"/>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>

</beans>

所以,component-scan@Controller@Autowired 的组合可以解决问题。

我在现实生活中不会从 Controller 访问 JdbcTemplate,而是通过服务和 dao 层,但现在这太复杂了......

【讨论】:

在 server.xml 中创建了这个资源,我从 /META-INF/context.xml 链接到它,对吗?此外,我在 Catalaina 日志中发现了另一个错误。也许这是主要问题:java.net.ConnectException:连接被拒绝:连接 我在 Tomcat 的 context.xml 中创建了这个资源(不是在 web 项目 /META-INF 中),我没有更改 server.xml... 好像写在context.xml和server.xml里都不管了。你希望我分享 DAO 的哪一部分?它很大。 @Misha:我添加了用于测试的示例配置,请编辑您的问题以指定您是否以不同方式使用它;-) 非常感谢您的回答。问题出在我的 context.xml 文件中,我在每一层都有几个,并且一些 bean 被定义了好几次。清理完所有工作后。

以上是关于Spring注入的DataSource为空的主要内容,如果未能解决你的问题,请参考以下文章

spring 中注入的对象为空

关于Spring依赖注入的问题

spring使用DataSoure注入参数时报No supported DataSource type found

spring+mybatis 注入properties文件中属性失败导致datasource加载失败的原因和解决

老王读Spring Transaction-6spring-tx与DataSource连接池整合的原理

Spring--Spring 注入