2013-09-26 104 views
0

我錯過了什麼? 我想用Hibernate創建一個基本的SpringMVC應用程序。我有另一個SpringMVC應用程序,我將其模型化,它的工作原理。 我顯然錯過了一些東西,我很茫然。任何幫助在這裏將不勝感激。再一雙眼睛可能會解決這個問題。也許我是盲人。NoSuchBeanDefinitionException Spring 3.2.2使用帶Maven 3的註解配置構建Hibernate 4

基本上錯誤是告訴我,我不能在我的控制器創建的CustomerService豆,因爲customerDao豆不能定位,因此不能被注入到該服務。

當我使用的IntelliJ我能夠跟隨Bean引用和一切似乎 被正確連接起來,但是當我運行的tomcat6或tomcat7得到以下錯誤:

Sep 26, 2013 10:13:02 AM org.springframework.web.context.ContextLoader initWebApplicationContext 
SEVERE: Context initialization failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mydomain.dao.CustomerDao com.mydomain.service.CustomerService.customerDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mydomain.dao.CustomerDao] 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)} 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1122) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) 
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) 
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) 
     at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) 
     at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) 
     at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) 
     at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4701) 
     at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5204) 
     at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5199) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
     at java.lang.Thread.run(Thread.java:724) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mydomain.dao.CustomerDao com.mydomain.service.CustomerService.customerDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mydomain.dao.CustomerDao] 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)} 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) 
     at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) 
     ... 21 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mydomain.dao.CustomerDao] 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)} 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:856) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768) 
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) 
     ... 23 more 
Sep 26, 2013 10:13:02 AM org.apache.catalina.core.StandardContext startInternal 

代碼如下:

的web.xml

<!DOCTYPE web-app PUBLIC 
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
"http://java.sun.com/dtd/web-app_2_3.dtd" > 

<web-app> 
    <display-name>Archetype Created Web Application</display-name> 

    <context-param> 
     <param-name>contextClass</param-name> 
     <param-value> 
      org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
     </param-value> 
    </context-param> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>com.mydomain.config.WebConfig</param-value> 
    </context-param> 
    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>spring</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextClass</param-name> 
      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
      </param-value> 
     </init-param> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>com.mydomain.config.WebConfig</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>spring</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 
</web-app> 

WebConfig.java

package com.mydomain.config; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Import; 
import org.springframework.validation.Validator; 
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 
import org.springframework.web.servlet.ViewResolver; 
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 
import org.springframework.web.servlet.view.InternalResourceViewResolver; 
import org.springframework.web.servlet.view.JstlView; 


@EnableWebMvc 
@Configuration 
@Import({DaoConfig.class, ServiceConfig.class, ControllerConfig.class}) 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public Validator getValidator(){ 
     return new LocalValidatorFactoryBean(); 
    } 

    @Bean 
    public ViewResolver getViewResolver() { 
     InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 
     resolver.setViewClass(JstlView.class); 
     resolver.setPrefix("/WEB-INF/pages/"); 
     resolver.setSuffix(".jsp"); 

     return resolver; 
    } 

    @Override 
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
     configurer.enable(); 
    } 
} 

DaoConfig.java

package com.mydomain.config; 

import java.util.Properties; 

import javax.sql.DataSource; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; 
import org.springframework.jdbc.datasource.DriverManagerDataSource; 
import org.springframework.orm.hibernate4.HibernateTransactionManager; 
import org.springframework.orm.hibernate4.LocalSessionFactoryBean; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

@Configuration 
@EnableTransactionManagement 
@ComponentScan({"com.mydomain.dao", "com.mydomain.service"}) 
public class DaoConfig { 
    @Bean 
    public LocalSessionFactoryBean getSessionFactory(){ 
     final LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean(); 
     sessionFactoryBean.setDataSource(getDataSource()); 
     sessionFactoryBean.setPackagesToScan(new String[]{"com.mydomain.domain"}); 
     sessionFactoryBean.setHibernateProperties(hibernateProperties()); 
     return sessionFactoryBean; 
    } 

    @Bean 
    public DataSource getDataSource(){ 
     final DriverManagerDataSource dmds = new DriverManagerDataSource(); 
     dmds.setDriverClassName("com.mysql.jdbc.Driver"); 
     dmds.setUsername("root"); 
     dmds.setPassword(""); 
     dmds.setUrl("jdbc:mysql://localhost/commandsearch"); 
     return dmds; 
    } 

    @Bean 
    public HibernateTransactionManager transactionManager() { 
     final HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(getSessionFactory().getObject()); 

     return txManager; 
    } 

    @Bean 
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { 
     return new PersistenceExceptionTranslationPostProcessor(); 
    } 

    final Properties hibernateProperties() { 
     return new Properties() { 
      { 
       setProperty("hibernate.hbm2ddl.auto", "update"); 
       setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); 
       setProperty("hibernate.show_sql", "true"); 
      } 
     }; 
    } 
} 

IAbstractDao.java

package com.mydomain.dao; 

import java.io.Serializable; 
import java.util.List; 

public interface IAbstractDao <T extends Serializable> { 
    T findOne(final long id); 
    List<T> findAll(); 
    void save(final T t); 
    void delete(final T t); 
    void deleteById(final long id); 
} 

AbstractHibernateDao.java

package com.mydomain.dao; 

import java.io.Serializable; 
import java.util.List; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 

public class AbstractHibernateDao<T extends Serializable> implements IAbstractDao<T> { 
    protected Class<T> entityClass; 
    protected final Log logger = LogFactory.getLog(getClass()); 

    protected AbstractHibernateDao(Class<T> entityClass){ 
     this.entityClass = entityClass; 
    } 

    @Autowired 
    private SessionFactory sessionFactory; 

    protected final Session getCurrentSession(){ 
     return sessionFactory.getCurrentSession(); 
    } 
    @Override 
    public T findOne(final long id) { 
     return ((T) getCurrentSession().get(entityClass, id)); 
    } 

    @Override 
    public List<T> findAll() { 
     return (List<T>)getCurrentSession().createQuery("from " + entityClass.getName()).list(); 
    } 

    @Override 
    public void save(final T t) { 
     getCurrentSession().saveOrUpdate(t); 
    } 

    @Override 
    public void delete(final T t) { 
     getCurrentSession().delete(t); 
    } 

    @Override 
    public void deleteById(final long id) { 
     final T entity = findOne(id); 
     delete(entity); 
    } 
} 

CustomerDao.java

package com.mydomain.dao; 

import org.springframework.stereotype.Repository; 

import com.mydomain.domain.Customer; 

@Repository 
public class CustomerDao extends AbstractHibernateDao<Customer> { 
    public CustomerDao(){ 
     this(Customer.class); 
    } 

    public CustomerDao(Class<Customer> entityClass){ 
     super(entityClass); 
    } 
} 

ServiceConfig.java

package com.mydomain.config; 

import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
@ComponentScan({"com.mydomain.service"}) 
public class ServiceConfig { 

} 

AbstractService.java

package com.mydomain.service; 

import java.io.Serializable; 
import java.util.List; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.springframework.transaction.annotation.Transactional; 

import com.mydomain.dao.IAbstractDao; 

@Transactional 
public abstract class AbstractService<T extends Serializable> { 
    protected final Log logger = LogFactory.getLog(getClass()); 

    public T findOne(final long id) { 
     return getDao().findOne(id); 
    } 

    public List<T> findAll() { 
     return getDao().findAll(); 
    } 

    public void save(final T entity) { 
     getDao().save(entity); 
    } 

    public void delete(final T entity) { 
     getDao().delete(entity); 
    } 

    public void deleteById(final long entityId) { 
     getDao().deleteById(entityId); 
    } 

    protected abstract IAbstractDao<T> getDao(); 
} 

CustomerService.java

package com.mydomain.service; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

import com.mydomain.dao.CustomerDao; 
import com.mydomain.dao.IAbstractDao; 
import com.mydomain.domain.Customer; 

@Service 
@Transactional 
public class CustomerService extends AbstractService<Customer>{ 

    @Autowired 
    private CustomerDao customerDao; 

    @Override 
    protected IAbstractDao<Customer> getDao() { 
     return customerDao; 
    } 
} 
+0

你應該拆分你的配置,目前你正在複製所有的bean實例,因爲'ContextLoaderListener'和'DispatcherServlet'都加載了相同的配置。 –

回答

0

你眼前的問題是這樣的

package com.mydomain.config; 

import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
@ComponentScan({"com.mydomain.service"}) 
public class ServiceConfig { 

} 

您掃描您的@Service類,但你有沒有在這方面,給你一個CustomerDao豆可用於注射,因此失敗,你有例外。


你的配置還有一堆其他的東西不對。您的DaoConfig掃描包含daoservice包。這對自己是不壞,但你把所有的其他XConfig類是多餘的。

此外,您的web.xml配置將創建2 WebConfig上下文,一個用於DispatcherServlet,另一個用於ContextLoaderListener

ContextLoaderListener應該加載根上下文DispatcherServlet應該加載servlet上下文

例如,DispatcherServlet應該加載WebConfig這樣

@EnableWebMvc 
@Configuration 
@Import(ControllerConfig.class) 
public class WebConfig extends WebMvcConfigurerAdapter { 

注它只@Import小號ControllerConfig

ContextLoaderListener如果您想進一步模塊化它,記住,@Import只能在@Configuration類或上下文中使用它,而不是上下文應該加載應用程序配置爲這樣

@Configuration 
@EnableTransactionManagement 
@ComponentScan({"com.mydomain.dao", "com.mydomain.service"}, ...) 
public class ApplicationConfig { 
    // all the @Bean methods from each of your other XxxConfig classes 
} 

正在進口。

+0

DaoConfig正在掃描com.mydomain.dao包,該包應該創建CustomerDao bean。我不需要ServiceConfig中的參考。 CustomerService類具有CustomerDao的Autowire引用。就DaoConfig掃描這兩個軟件包而言,我已經嘗試過並且沒有掃描服務軟件包。我有這個web.xml工作在一個不同的應用程序,有小的差異。我不記得爲什麼我這麼做了,但是在其他應用程序中都需要這兩個東西 – John

+0

@John牛肉是'DaoConfig'正在使用'@Import(ServiceConfig.class)',它正在嘗試用'@ Service'類加載上下文,該類需要注入_that_上下文中不存在的'CustomerDao' bean。你的上下文只是配置不正確。仔細閱讀我的答案。 –

+0

我不確定DaoConfig如何使用@Import(ServiceConfig.class)WebConfig執行所有導入操作,並且每個配置都處理它們自己的ComponentScan。我有這個設置在另一個應用程序中工作。我在另一個應用程序中唯一的區別是每個dao都有一個接口。我在這裏跳過了。 Intellij能夠遵循IDE中的bean聲明。我曾嘗試拆分ContextLoader和DispatchServlet,我只是試圖避免聲明每個bean。 – John

相關問題