2013-10-10 79 views
0

我在尝试自动装入扩展JdbcDaoSupport的类时收到错误。我有我的DAO类和控制器类分成2个不同的春天上下文。 DAO类位于根上下文中,Controller类位于servlet上下文中。我已经设置了组件扫描,以便两个上下文之间的bean没有重叠(是否是正确的模式?)。所有这些因素加上我的DAO扩展了JdbcDaoSupport这一事实似乎导致了这个问题,我不明白为什么。我只是在学习春天,所以我还没有完全理解所有的概念。Spring Autowire JdbcDaoSupport

编辑:此行为似乎是由JdbcDaoSupport/DaoSupport实现InitializingBean接口的事实引起的。尽管如此,仍然困惑。

这里是我收到的错误:

Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.test.dao.CustomerDAO2 org.test.servlet.HomeController.customerDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.test.dao.CustomerDAO2] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

这里是我的文件:

HomeController.java

package org.test.servlet; 

import java.util.Locale; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

import org.test.dao.*; 

@Controller 
public class HomeController 
{ 
    @Autowired 
    CustomerDAO2 customerDAO; 

    @RequestMapping(value = "/", method = RequestMethod.GET) 
    public String home(Locale locale, Model model) 
    { 
     model.addAttribute("customer", customerDAO.getCustomer()); 
     return "home"; 
    } 
} 

CustomerDAO2.java

package org.test.dao; 

import java.sql.ResultSet; 
import java.sql.SQLException; 
import javax.sql.DataSource; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.jdbc.core.*; 
import org.springframework.jdbc.core.support.JdbcDaoSupport; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.*; 
import org.test.dto.Customer; 

@Repository 
public class CustomerDAO2 extends JdbcDaoSupport 
{ 
    public CustomerDAO2() 
    { 
    } 

    @Autowired 
    public CustomerDAO2(DataSource datasource) 
    { 
     this.setDataSource(datasource); 
    } 

    @Transactional 
    public Customer getCustomer() 
    { 
     JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSource()); 
     Customer customer = jdbcTemplate.queryForObject("select * from customer", new CustomerMapper()); 
     return customer; 
    } 

    public static class CustomerMapper implements RowMapper<Customer> 
    { 
     public Customer mapRow(ResultSet rs, int rowNum) throws SQLException 
     { 
      Customer customer = new Customer(); 
      customer.setCustomerId(rs.getInt("customerId")); 
      customer.setCustomerNumber(rs.getString("customerNumber")); 
      return customer; 
     } 
    } 
} 

应用程序的context.xml

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

    <!-- Scans within the base package of the application for @Components to configure as beans --> 
    <!-- @Controller, @Service, @Configuration, etc. --> 
    <context:component-scan base-package="org.test"> 
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> 
    </context:component-scan> 

    <!-- Enables the configuration of transactional behavior based on annotations --> 
    <tx:annotation-driven transaction-manager="transactionManager"/> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url" value="jdbc:mysql://localhost/crm?user=root&amp;password=password" /> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"/> 
    </bean> 

</beans> 

的servlet-context.xml的

<?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:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context" 
    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 within the base package of the application for @Components to configure as beans --> 
    <!-- @Controller, @Service, @Configuration, etc. --> 
    <context:component-scan base-package="org.test.servlet"/> 

    <!-- Enables the Spring MVC @Controller programming model --> 
    <mvc:annotation-driven /> 

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> 
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/views/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 

</beans> 

回答

1

我发现我在这个岗位回答:

Spring expected at least 1 bean which qualifies as autowire candidate for this dependency


基本上,我需要为我的DAO类创建一个接口。事情是这样的:

public interface ICustomerDAO { 
    Customer getCustomer(); 
} 

注:它可能会更好做一个更通用的CRUD接口。

然后你使用依赖注入的接口类型,而不是使用类类型:

@Autowired 
ICustomerDAO customerDAO; 

之所以这样,是因为春天创建底层的代理类:

http://insufficientinformation.blogspot.com/2007/12/spring-dynamic-proxies-vs-cglib-proxies.html

http://docs.spring.io/spring/docs/2.5.x/reference/aop.html#aop-proxying