Spring 注入的数据源为空
Spring injected DataSource is null
我正在尝试使用 JdbcTemplate 创建 DAO。但似乎 Spring 注入不顺利。我正在使用 Tomcat.
中的 JNDI 注入 DataSource
我还在 Tomcats server.xml 中写了设置,在 /META-INF 中写了 ResourceLink,在 web.xml 中写了 resource-ref,试图在 [=37= 中添加上下文侦听器],它也无济于事(实际上,如果我不是从 servlet 访问数据源,而是仅从 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"/>
server.xml 在 Tomcat
<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 卡特琳娜日志
http://shorttext.com/700f24cb
与我的工作示例相比,我能看到的唯一区别是,我在 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 代码吗?
嗨,Misha,很抱歉回答晚了。
我创建了非常简单的控制器来测试:
@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 层,但现在这太复杂了...
我正在尝试使用 JdbcTemplate 创建 DAO。但似乎 Spring 注入不顺利。我正在使用 Tomcat.
中的 JNDI 注入 DataSource我还在 Tomcats server.xml 中写了设置,在 /META-INF 中写了 ResourceLink,在 web.xml 中写了 resource-ref,试图在 [=37= 中添加上下文侦听器],它也无济于事(实际上,如果我不是从 servlet 访问数据源,而是仅从 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"/>
server.xml 在 Tomcat
<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 卡特琳娜日志 http://shorttext.com/700f24cb
与我的工作示例相比,我能看到的唯一区别是,我在 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 代码吗?
嗨,Misha,很抱歉回答晚了。
我创建了非常简单的控制器来测试:
@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 层,但现在这太复杂了...