1.通过类的无参构造创建对象

当用最普通方式配置一个<bean>时,默认就是采用类的无参构造创建对象。在Spring容器初始化时,通过<bean>上配置的class属性反射得到字节码对象,通过newInstance()创建对象。

(详细的创建方式,参见:https://blog.csdn.net/qq_32224047/article/details/106957319

newInstance()创建对象过程:

Class c = Class .forName("类的全路径名称")

Object obj = c.newInstance()

查询API找到Class类的newInstance方法

 

查阅API说明(newInstance()方法的本质就是利用这个类的无参构造器创建了一个对象,并返回给你)

这种方式下spring创建对象,要求类必须有无参的构造,否则无法通过反射创建对象,会抛出异常

2.通过类的有参构造创建对象

有上面的异常引出了有参构造创建对象,下面将进行验证:

Person类中添加有参构造

public class Person {
    /**
     *添加有参数构造器
     */
    public Person(String name,Dog dog) {
        System.out.println("name:"+name+"|dog:"+dog+"|"+this);
    }

    /**
     * person的eat方法
     */
    public void eat(){
        System.out.println("eating...");
    }
}

执行抛出异常:BeanInstantiationException

注意观察的话,编译器也会检查出配置文件并提示异常

 

解决上述问题的方法:只需要配置时指定让spring去使用有参构造器即可

使用标签为:constructor-arg

标签中的参数:

name--参数名,type--参数类型,index--参数位置(从0开始),value--参数值(直接赋值),ref--参数值(引用其他bean)

注意:

  • value 和ref  只能用一个
  • 参数可以只配置一部分,不用都配置(能确认出那个参数就行,也可以都写全,准确定位)
  • 引用类型用ref,指定后就不在用newinstance 方法,当容器解析到constructor-arg标签时,会去调用Class的getConstructor(类<?>... parameterTypes) 方法,返回一个 Constructor对象

有参构造器创建对象过程:

1.通过getConstructor 创建getConstructor的对象

Constructor cs = getConstructor(xxxx)

2.通过该对象去调用newInstance()方法创建对应类的对象

Person  obj = cs.newInstance(xxxxx)

代码示例:

在applicationContext.xml中配置 constructor-arg,为了方便观察,并使用value和ref 给参数赋值,ref 传入Dog类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="person" class="cn.ww.beans.Person">
        <constructor-arg name="name" type="java.lang.String" index="0" value="张三"/>
        <constructor-arg name="age" type="int" index="1" value="18"/>
        <constructor-arg name="dog" type="cn.ww.beans.Dog" index="2" ref="dog"/>
    </bean>
    <bean id="dog" class="cn.ww.beans.Dog"/>
</beans>

Person类:

package cn.ww.beans;

public class Person {
    /**
     *添加有参数构造器
     */
    public Person(String name,int age,Dog dog) {
        System.out.println("name:"+name+"age:"+age+"|dog:"+dog+"|"+this);
        dog.walk();
    }

    /**
     * person的eat方法
     */
    public void eat(){
        System.out.println("eating...");
    }
}

Dog类

package cn.ww.beans;


public class Dog {
    public void walk(){
        System.out.println("dog is walking...");
    }
}

测试验证spring 创建对象,调用方法成功

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐