我错过了什么?我正在尝试使用 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;
}
}