การฉีดการขึ้นต่อกันแบบ autowired ล้มเหลว ข้อยกเว้นแบบซ้อนคือ org.springframework.beans.factory.BeanCreationException:

ฉันกำลังพยายามสร้างตัวอย่างจากธุรกรรมสปริงด้วย apache tomcat และ postgresql แต่ได้รับข้อผิดพลาด การฉีดการพึ่งพาแบบ autowired ล้มเหลว

ข้อยกเว้น

javax.servlet.ServletException: Servlet.init() for servlet dispatcher threw exception
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:724)

root cause

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private DAO.TblUserManager_DAO Controllers.LoginController.user; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [DAO.TblUserManager_DAO] is defined: expected single matching bean but found 2: [tblUserManager_DAOImpl, TblUserManager_DAOImpl]
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
    javax.servlet.GenericServlet.init(GenericServlet.java:212)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:724)

root cause

org.springframework.beans.factory.BeanCreationException: Could not autowire field: private DAO.TblUserManager_DAO Controllers.LoginController.user; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [DAO.TblUserManager_DAO] is defined: expected single matching bean but found 2: [tblUserManager_DAOImpl, TblUserManager_DAOImpl]
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
    org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
    javax.servlet.GenericServlet.init(GenericServlet.java:212)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:724)

root cause

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [DAO.TblUserManager_DAO] is defined: expected single matching bean but found 2: [tblUserManager_DAOImpl, TblUserManager_DAOImpl]
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
    javax.servlet.GenericServlet.init(GenericServlet.java:212)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:724)

dispacher-servlet.xml ของฉัน

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd        
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:annotation-config />
    <context:component-scan base-package="Controllers" /> 
    <context:component-scan base-package="DAO" />
    <mvc:annotation-driven />
    <tx:annotation-driven transaction-manager="transactionManager"/> 


    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/car" />
        <property name="username" value="----" />
        <property name="password" value="-----" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="annotatedClasses" >
            <list>
                <value>DAOModel.Tblusers</value>
                <value>DAOModel.Tblcars</value>
            </list>
        </property>
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="DAOModel" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <!-- <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> -->
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id = "Tblusers_DAOImpl" class="DAO.Tblusers_DAOImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
   <bean id = "TblUserManager_DAOImpl" class="DAO.TblUserManager_DAOImpl">

    </bean>
</beans>

พื้นที่เก็บข้อมูล บริการ ส่วนประกอบของฉัน

    @Component
    public interface Tblusers_DAO {
        public void adduser(Tblusers user);
    }


    @Repository
    public class Tblusers_DAOImpl implements Tblusers_DAO{

        @Autowired
        private SessionFactory sessionFactory;

        @Override
        public void adduser(Tblusers user) {
            this.getSessionFactory().getCurrentSession().saveOrUpdate(user);
        }


        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }


        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
    }



@Component
public interface TblUserManager_DAO {
    public void adduser(Tblusers user);
}



@Service
public class TblUserManager_DAOImpl implements TblUserManager_DAO{

    @Autowired
    private TblUserManager_DAO dao;

    @Override
    @Transactional
    public void adduser(Tblusers user) {
       dao.adduser(user);
    }

    public void setDao(TblUserManager_DAO dao) {
        this.dao = dao;
    }

}

และผู้ควบคุม

public class LoginController {

    @Autowired
    private  TblUserManager_DAO user;
    @RequestMapping(value = "/Login", method = RequestMethod.POST)
    public ModelAndView setLgin(@ModelAttribute("LoginModel") LoginModel login) {
        ModelAndView model = new ModelAndView();
        Tblusers user2=new Tblusers();
        user2.setTblusersId(3);
        user2.setTblusersFamily(login.getUsername());
        user2.setTblusersPassword(login.getPassword());
        user.adduser(user2);
        model.addObject("Hello", login.getUsername());
        return model;
    }
 public void setUser(TblUserManager_DAO user) {
        this.user = user;
    }

}

person ATJVS    schedule 15.02.2014    source แหล่งที่มา
comment
เป็นไปได้ที่ซ้ำกันของ BeanCreationException ใน Spring Autowiring   -  person Brian Clozel    schedule 16.02.2014


คำตอบ (3)


เมื่อคุณสแกนส่วนประกอบคลาสด้วยคำอธิบายประกอบ @Component, @Repository, @Service, @Configuration ฯลฯ Spring จะสร้าง bean ขึ้นมาโดยปริยาย นอกจากนี้ยังสร้าง bean ขึ้นมาเมื่อคุณประกาศอย่างชัดเจน เช่น นี้

<bean id = "Tblusers_DAOImpl" class="DAO.Tblusers_DAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id = "TblUserManager_DAOImpl" class="DAO.TblUserManager_DAOImpl">

ขณะนี้คุณมีถั่วสองตัวสำหรับ TblUserManager_DAOImpl และ Tblusers_DAOImpl สปริงไม่รู้ว่าจะฉีดอันไหนในทุ่งแบบนี้

@Autowired
private  TblUserManager_DAO user;

เพราะมีผู้สมัครสองคน ลบการประกาศ <bean> หรือกำหนดคุณสมบัติเป้าหมายการฉีดด้วย @Qualified เพื่อเลือก bean ที่เหมาะสม

นี่คือเอกสารประกอบ อ่านรายละเอียดทั้งหมดเพื่อทำความเข้าใจกระบวนการสแกนส่วนประกอบทั้งหมด


ตามที่ JB Nizet ระบุไว้ ด้านล่าง คุณควรใส่คำอธิบายประกอบคลาสการใช้งานจริงด้วย @Component หรือความเชี่ยวชาญพิเศษใดๆ เท่านั้น ลองคิดในแง่ความหมายว่าอินเทอร์เฟซไม่ใช่ส่วนประกอบ ไม่สามารถสร้าง bean สำหรับอินเทอร์เฟซได้ เฉพาะคลาสจริงซึ่งเป็นการนำอินเทอร์เฟซไปใช้เท่านั้นที่สามารถเป็นส่วนประกอบได้

person Sotirios Delimanolis    schedule 15.02.2014
comment
+1. และอย่าใส่คำอธิบายประกอบอินเทอร์เฟซของ bean ด้วย @Component ควรใส่คำอธิบายประกอบเฉพาะการใช้งานเท่านั้น - person JB Nizet; 15.02.2014
comment
โซลูชันนี้ใช้ไม่ได้เมื่อฉันเพิ่ม @Qualifier(user) ใน Controller - person ATJVS; 15.02.2014
comment
@ATJVS อธิบายให้ฉันฟังว่าทำไมคุณถึงมีคุณสมบัติด้วยค่า user ทำไมคุณถึงคิดว่าควรจะได้ผล? - person Sotirios Delimanolis; 15.02.2014
comment
เพราะมีผู้สมัครสองคน ลบการประกาศ ‹bean› หรือกำหนดคุณสมบัติเป้าหมายการแทรกด้วย @Qualified - person ATJVS; 15.02.2014
comment
@ATJVS ใช่ แต่ทำไมถึงมีค่า user นี่คือ บทเกี่ยวกับวิธีการใช้ @Qualifier จากเอกสารประกอบ - person Sotirios Delimanolis; 15.02.2014

ลงทะเบียน bean ของคุณผ่านรายการ beandefenition ในไฟล์ xml หรือผ่านคำอธิบายประกอบ เช่น @component,@Repository,@Service.Moreover,

<context:annotation-config/> and <context:component-scan/>

องค์ประกอบทั้งสองนี้ถูกใช้ในโค้ดของคุณ คุณสามารถใช้ <context:component-scan/> ได้อย่างเหมาะสม เนื่องจากจะทำสิ่งเดียวกันกับองค์ประกอบอื่น และเพื่อหลีกเลี่ยงความคลุมเครือ

person Magesh    schedule 12.04.2014

เมื่อใดก็ตามที่คุณฉีดอ็อบเจ็กต์ใดๆ คุณต้องจัดเตรียมเมธอด setter และ getter ของมัน มันจะแก้ไขปัญหาของคุณ

person Shivshanker Mhadiwale    schedule 14.07.2015