Spring通過無參構造及有參構造創建對象方法詳解

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 創建對象,調用方法成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章