0

我错过了什么?我正在尝试使用 Hibernate 创建一个基本的 SpringMVC 应用程序。我有另一个 SpringMVC 应用程序,我对其进行建模并且它可以工作。我显然错过了一些东西,我不知所措。在这里的任何帮助将不胜感激。只需另一双眼睛就可以解决问题。也许我是盲人。

基本上,错误告诉我无法在控制器中创建 customerService bean,因为无法找到 customerDao bean,因此无法将其注入服务中。

当我使用 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);
    }
}

服务配置.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 {

}

抽象服务.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();
}

客户服务.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;
    }
}
4

1 回答 1

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您没有任何内容可以为您提供可用于注入的 bean,因此它会失败,但您有例外。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 {

注意它只有@Imports ControllerConfig

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使用它的类或上下文,而不适用于正在导入的上下文。

于 2013-09-26T17:33:52.010 回答