2013-09-26 2 views
0

Что мне не хватает? Я пытаюсь создать базовое приложение SpringMVC с помощью Hibernate. У меня есть еще одно приложение SpringMVC, которое я моделирую после этого, и оно работает. Я, очевидно, что-то пропустил, и я в недоумении. Любая помощь здесь была бы высоко оценена. Еще одна пара глаз может решить проблему. Может быть, я слепой.NoSuchBeanDefinitionException Spring 3.2.2 Hibernate 4 с использованием построения конфигурации аннотации с Maven 3

В основном ошибка говорит мне, что я не могу создать компонент customerService в своем контроллере, потому что компонент customerDao не может быть расположен и поэтому не может быть введен в службу.

Когда я использую IntelliJ Я могу следовать ссылки боб и все, кажется, быть подключен правильно, но когда я бегу в 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 сканирует как dao, так и service. Это само по себе неплохо, но у вас есть все остальные XConfig классы, которые являются избыточными.

Кроме того, конфигурация web.xml собирается создать 2 WebConfig контексты, один для DispatcherServlet и один для ContextLoaderListener.

Ваш ContextLoaderListener должен загрузить корневой контексти DispatcherServlet должен загрузить контекст сервлета.

Например, DispatcherServlet должен загрузить WebConfig как таковой

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

Обратите внимание на это только @ImportControllerConfig сек.

Ваш ContextLoaderListener должен загрузить конфигурации приложения в качестве такого

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

Если вы хотите модуляризуете его дальше, имейте в виду, что @Import работает только на @Configuration класса или контекста, который использует его, а не на контексте импортируется.

+0

DaoConfig сканирует com.mydomain.dao пакет, который должен создать компонент CustomerDao. Мне не нужна ссылка в ServiceConfig. Класс CustomerService имеет ссылку Autowire на CustomerDao. Насколько DaoConfig сканирует оба пакета, я пробовал его с и без сканирования пакета услуг. У меня этот web.xml работает в другом приложении с небольшими отличиями. Я не помню, что я сделал это, но было что-то, что было необходимо как в другом приложении. – John

+0

@John Говядина - это то, что 'DaoConfig' использует' @Import (ServiceConfig.class) ', который пытается для загрузки контекста с помощью класса '@ Service', который требует ввода компонента' CustomerDao', который не существует в _that_ контексте. Ваши контексты настроены неправильно. Внимательно прочитайте мой ответ. –

+0

Я не уверен, как DaoConfig использует @Import (ServiceConfig.class). WebConfig выполняет все импорт, и каждая из конфигураций обрабатывает свой собственный компонент ComponentScan. У меня эта настройка работает в другом приложении. Единственное отличие, которое у меня есть в другом приложении: у меня есть интерфейс для каждого дао. Я пропустил это здесь. Intellij может следить за объявлениями в среде IDE. Я попытался разделить ContextLoader и DispatchServlet, я просто пытался избежать объявления каждого компонента. – John

Смежные вопросы