2013-10-10 112 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