org.springframework.beans.factory.UnsatisfiedDependencyException:创建bean时出错...预期的单个匹配bean但找到12

时间:2016-06-27 15:00:15

标签: java spring hibernate generics dao

到目前为止,我创建的程序大约有12个DAO和服务。 DAO和服务主要是相同的,所以我构建了一个通用的DAO和服务,它由我制作的12个DAO和服务扩展,因此他们都可以访问保存,更新,删除和findById 。每当我只使用一个类进行测试(RegularUser)时,一切都运行得很好但是当我将所有类切换到扩展通用DAO和服务时,我得到了这个错误:

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'genericServiceImpl' defined in file [C:\Users\Contronym\workspace\Glimps App\target\classes\com\glimpsmedia\app\generic\service\GenericServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [com.glimpsmedia.app.generic.dao.GenericDao] is defined: expected single matching bean but found 12: businessCategoryDaoImpl,businessUserDaoImpl,campaignCategoryDaoImpl,campaignDaoImpl,competitorDaoImpl,followDaoImpl,friendDaoImpl,giveawayDaoImpl,glimpsDaoImpl,regularUserDaoImpl,userCategoryDaoImpl,viewDaoImpl; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.glimpsmedia.app.generic.dao.GenericDao] is defined: expected single matching bean but found 12: businessCategoryDaoImpl,businessUserDaoImpl,campaignCategoryDaoImpl,campaignDaoImpl,competitorDaoImpl,followDaoImpl,friendDaoImpl,giveawayDaoImpl,glimpsDaoImpl,regularUserDaoImpl,userCategoryDaoImpl,viewDaoImpl
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.glimpsmedia.app.main.App.main(App.java:14)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.glimpsmedia.app.generic.dao.GenericDao] is defined: expected single matching bean but found 12: businessCategoryDaoImpl,businessUserDaoImpl,campaignCategoryDaoImpl,campaignDaoImpl,competitorDaoImpl,followDaoImpl,friendDaoImpl,giveawayDaoImpl,glimpsDaoImpl,regularUserDaoImpl,userCategoryDaoImpl,viewDaoImpl
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:172)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1059)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1018)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:834)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    ... 15 more

我的通用DAO:

public class GenericDaoImpl<T> implements GenericDao<T> {

    @Autowired
    private SessionFactory sessionFactory;

    private final Class<T> type;

    public GenericDaoImpl(final Class<T> type) {
        this.type = type;
    }

    public void save(final T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.save(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public void update(final T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.update(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public void delete(final T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.delete(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public T findById(final long id) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        T obj = null;
        try {
            tx = session.beginTransaction();
            obj = session.get(type, id);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

        return obj;
    }

}

我的通用服务:

@Service
@Transactional
public class GenericServiceImpl<T> implements GenericService<T> {

    private GenericDao<T> dao;

    @Autowired
    public GenericServiceImpl(GenericDao<T> dao) {
        this.dao = dao;
    }

    public void save(T obj) {
        dao.save(obj);
    }

    public void update(T obj) {
        dao.update(obj);
    }

    public void delete(T obj) {
        dao.delete(obj);
    }

    public T findById(long id) {
        return dao.findById(id);
    }

}

此外,这是其中一个DAO的示例。除了班级名称(其中有12个)之外,他们都是一样的:

@Repository("regularUserDaoImpl")
public class RegularUserDaoImpl extends GenericDaoImpl<RegularUser> 
    implements RegularUserDao {

    public RegularUserDaoImpl() {
        super(RegularUser.class);
    }

}

一个服务的例子(再次,其中有12个,每个DAO一个):

@Service("regularUserServiceImpl")
@Transactional
public class RegularUserServiceImpl extends GenericServiceImpl<RegularUser> 
    implements RegularUserService {

    public RegularUserServiceImpl(GenericDao<RegularUser> dao) {
        super(dao);
    }

}

我尝试对此进行一些研究,并看到有关@Qualifier标记的内容,但由于泛型类中的@Autowired标记,我不知道我是如何在此处实现的有12种不同的选项可供选择,因此我不知道将哪些内容放入@Qualifier或如何使@Qualifier动态化。

2 个答案:

答案 0 :(得分:1)

@Service删除GenericServiceImpl注释,它告诉Spring使用通用DAO创建通用服务,这可能不是您想要的。还有一个建议:make GenericDaoImplGenericServiceImpl是抽象的,所以没有人试图实例化它们。
@Qualifier@Primary

中没有必要

答案 1 :(得分:0)

结束修复它。在Spring 4.0及更高版本中不需要@Qualifier。我最终将@Primary标签添加到我的一个DAO中。解决了问题,现在一切都很完美。 Spring会因某种原因而感到困惑,除非你有一个DAO之上的@Primary