【问题标题】:@Resource using Spring MVC and tomcat@Resource 使用 Spring MVC 和 tomcat
【发布时间】:2014-11-27 18:34:45
【问题描述】:

我正在学习 Spring MVC。我正在尝试使用@Resource 注入数据源。是这样的:

Tomcat的web.xml:

<resource-ref>
  <description>DB Connection</description>
  <res-ref-name>jdbc/TestDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

context.xml:

Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
           maxActive="100" maxIdle="30" maxWait="10000"
           username="sa" password="" driverClassName="org.h2.Driver"
           url="jdbc:h2:tcp://localhost/~/test"/>

控制器代码(使用Spring MVC框架):

@Controller
public class SimpleControllerAnnotation {

//@Resource(name="dataSource")
@Resource(name="jdbc/TestDB")
private DataSource dataSource;

public DataSource getDataSource() {
    return dataSource;
}

//@Resource(name="dataSource")
@Resource(name="jdbc/TestDB")
public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}

@RequestMapping("/testDataSource")
public ModelAndView testDataSource() {

    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;
    String name = null;
    String ID = null;

    try {
        con = dataSource.getConnection();
        stmt = con.createStatement();
        rs = stmt.executeQuery("select ID, name from STUDENT");
        while(rs.next()){
            name = rs.getString("name");
            ID = rs.getString("ID");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
            try {
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
    }

    ModelAndView mw = new ModelAndView("TestDataSourceForm");
    mw.addObject("DataSourceValue",dataSource);
    mw.addObject("Name",name);
    mw.addObject("ID",ID);

    return mw;
}

在这段代码中,我使用@Resource 来注入我打算从Tomcat 中“获取”的DataSource,它是我在Tomcat 中设置的(上面共享的web.xml 和context.xml)。

当我运行这个程序时,我得到以下异常:

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name    'simpleControllerAnnotation': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'jdbc/TestDB' is defined

jdbc/TestDB是我在Tomcat中设置的DataSource。

我有以下疑问:

1) 是否可以将我们在 Tomcat 中创建的 DataSource 以这种方式注入?或者我们必须使用 JNDI 查找。在我在互联网上阅读的一篇文章中,有人说 JNDI 查找有点过时了,现在依赖注入是首选方式。

2) 一般而言,最佳实践是在应用服务器/Web 容器中设置数据源还是在应用程序本身中进行管理。从我读到的帖子来看,最好让 App server/Container 来管理这个。

非常感谢您对解决此错误的任何帮助。

【问题讨论】:

标签: java spring spring-mvc tomcat datasource


【解决方案1】:
  1. Apache Tomcat 仅在其自身加载的类(例如过滤器、Servlet 和侦听器)上处理 @Resource 注释。

    在您的情况下,您的控制器类由 Spring Framework 加载,Spring 负责处理 @Resource 注释。阅读 Spring 文档(参考指南)。

  2. 根据 Spring 参考指南 [1],@Resource 注解中的值是 Spring bean 的名称。

    它说如果你配置一个 SimpleJndiBeanFactory,这个名字可以用于 JDNI 查找,但建议不要使用它,并建议显式配置引用的 bean。 -> [2]

[1]http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-resource-annotation

[2]http://docs.spring.io/spring/docs/current/spring-framework-reference/html/xsd-config.html#xsd-config-body-schemas-jee

【讨论】:

  • 谢谢!但是,如果我们有应用程序服务器/servlet 容器设置的数据存储,那么我们该如何使用呢?我认为使用@Resouce 注释,我们可以注入我在Tomcat 中设置的数据源。我能够这样做,使用 JNDI。实际上,我们没有办法直接使用我们在App server / servlet容器中设置的数据源吗?
  • 可以注射,但需要有人注射。对于您的控制器类,容器是 Spring,而不是 Tomcat。仔细阅读 Spring 文档——当 Spring 执行注入时,它注入了什么以及它是如何配置的。
  • 非常感谢您的回复!
猜你喜欢
  • 2014-08-24
  • 2014-03-14
  • 2021-01-03
  • 2011-12-18
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多