org.springframework.beans.factory.UnsatisfiedDependencyException异常的解决方案

现象

使用spring框架,创建对象时应用类型数据采用自动注入的方式,采用byName的语法格式。
xml配置文件:

<bean id="school" class="com.bupt.implement_class.ba01.School">
        <property name="name" value="北京大学"/>
        <property name="address" value="北京市海淀区"/>
    </bean>
    <bean id="student1" class="com.bupt.implement_class.ba01.Student" autowire="byName">
        <constructor-arg name="name" value="张振仁"/>
        <constructor-arg name="age" value="23"/>
    </bean>

这里新建的类是Student 引用数据类型为School;
测试类代码:

public class TestStudent {
    @Test
    public void test01(){
        String config="ba01/applicationContext.xml";
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(config);
        Student student=(Student) applicationContext.getBean("student1");
        System.out.println(student);
    }
}

运行会出现如下错误:

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'student1' defined in class path resource [ba01/applicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 2: Ambiguous argument values for parameter of type [com.bupt.implement_class.ba01.School] - did you specify the correct bean references as arguments?

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'student1' defined in class path resource [ba01/applicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 2: Ambiguous argument values for parameter of type [com.bupt.implement_class.ba01.School] - did you specify the correct bean references as arguments?

回去仔细检查配置文件和测试类,发现写的没有任何问题。

解决方法

第一步:找到需要测试的类,在类中加上无参数构造方法;
第二部,在applicationContext.xml配置文件中,创建对象时,使用set注入给属性赋值,使用赋值。
修改后的Student的代码:

package com.bupt.implement_class.ba01;
public class Student {
    private String name;
    private int age;
    private School school;
    public Student() {
    }
    public Student(String name, int age, School school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setSchool(School school) {
        this.school = school;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

修改后的配置文件

<bean id="school" class="com.bupt.implement_class.ba01.School">
        <property name="name" value="北京大学"/>
        <property name="address" value="北京市海淀区"/>
    </bean>
    <bean id="student1" class="com.bupt.implement_class.ba01.Student" autowire="byName">
        <property name="name" value="张振仁"/>
        <property name="age" value="23"/>
    </bean>

这样运行就没有问题。
我只测试了使用byName,个人感觉使用byType也一样的。

原因

spring使用bean创建对象时,先找类中的构造方法,如果没有写构造方法,则默认为无参数构造方法;如果写了有参数的构造方法,并且没有写无参数构造方法,则只调用有参数构造方法,而采用构造方法注入的方式给属性赋值,要求在创建对象时把参数传递进去,并且使用时,如果参数没有写完成,代码会爆红出错,就达不到自动注入的目的了。
而我一开始配置文件用的是的方式,但是到了运行阶段就发现依赖不正确,要求无参数构造创建对象,然后set注入赋值,但是类中没有无参数构造方法。

总结

总结:引用类型自动注入应该选用给简单属性赋值,并且在需要测试的类中写明无参数构造方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值