2.spring IOC(DI)

1. IOC(DI) - 控制反轉(依賴注入)java

       所謂的IOC稱之爲控制反轉,簡單來講就是將對象的建立的權利及對象的生命週期的管理過程交由Spring框架來處理,今後在開發過程當中再也不須要關注對象的建立和生命週期的管理,而是在須要時由Spring框架提供,這個由spring框架管理對象建立和生命週期的機制稱之爲控制反轉。簡單來講就是原來是咱們本身在各層建立其餘層的對象和銷燬對象,容易形成程序層與層之間的耦合,如今spring容器幫咱們建立和管理對象,在咱們要使用的時候給咱們。 而在 建立對象的過程當中Spring能夠依據配置對對象的屬性進行設置,這個過稱之爲依賴注入,也即DI。web

      

2. IOC的入門案例spring

       a. 下載Springexpress

              訪問Spring官網,下載Spring相關的包app

       b. 解壓下載好的壓縮包框架

              其中包含着Spring的依賴包dom

       c. 建立一個java項目ide

              spring並非非要在javaweb環境下才可使用,一個普通的java程序中也可使用Spring。測試

       d. 導入Spring的libs目錄下IOC相關的jar包this

             

 

       beans是一種根標籤

       context是上下文

    core是核心包包括了c3p0鏈接池

   expression是表達式

       a. 建立Spring的配置文件

              Spring採用xml文件做爲配置文件,xml文件名字任意,但一般都取名爲applicationContext.xml,一般將該文件放置在類加載的目錄裏下(src目錄),方便後續使用。

建立bean類,並在spring中進行配置交由spring來管理

            1     <?xml version="1.0" encoding="UTF-8"?>
            2     <beans xmlns="http://www.springframework.org/schema/beans" 
            3             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            4             xsi:schemaLocation="http://www.springframework.org/schema/beans 
            5             http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
            6             
            7             <bean id="person" class="domain.Person"></bean>
            8             
            9     </beans>
<bean id="person" class="domain.Person"></bean>  
1.beanBean理解爲類的代理或代言人(實際上確實是經過反射、代理來實現的),這樣它就能表明類擁有該擁有的東西了,
2.id表明用於區分bean不可重複
3.class後面的domain.Person是咱們經過class.forname(.class)方法反射時須要的參數,forname方法的參數是包名+類名

在程序中經過Spring容器獲取對象並使用

.java文件

package cn.tedu.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.tedu.domain.Person;

public class Test01 {
    
    /**
     * Spring中不能夠配置多個id相同的bean,在容器初始化時會拋出異常
     */
    @Test
    public void test(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基於Spring容器建立對象 
        Person p1 = (Person) context.getBean("person");
        Person p2 = (Person) context.getBean("person2");
        p.say();
System.out.println(p1); System.out.println(p2); } 

/** * 1.能夠配置多個id不一樣但類型相同(即反射指向的類是同一個)的bean,spring內存儲的是不一樣的對象
* 2.默認狀況下屢次獲取同一個id的bean獲得的是同一個對象

**/
}

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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ">
    <bean id="person" class="cn.tedu.domain.Person"></bean>
    <bean id="person2" class="cn.tedu.domain.Person"></bean>
</beans>
 

3. IOC的實現原理

       在初始化一個Spring容器時,Spring會去解析指定的xml文件,當解析到其中的<bean>標籤時,會根據該標籤中的class屬性指定的類的全路徑名,經過反射建立該類的對象,並將該對象存入內置的Map中管理。其中鍵就是該標籤的id值,值就是該對象。

       以後,當經過getBean方法來從容器中獲取對象時,其實就是根據傳入的條件在內置的Map中尋找是否有匹配的鍵值,若是有則將該鍵值對中保存的對象返回,若是沒有匹配到則拋出異常。

      

       由此能夠推測而知:

              默認狀況下,屢次獲取同一個id的bean,獲得的將是同一個對象。

              即便 是同一個類,若是配置過多個<bean>標籤具備不一樣的id,每一個id都會在內置Map中有一個鍵值對,其中的值是這個類建立的不一樣的對象

              同一個<beans>標籤下不容許配置多個同id的<bean>標籤,若是配置則啓動拋異常

 
經過反射建立對象

 

4. IOC獲取對象的方式

 

       經過context.getBeans()方法獲取bean時,能夠經過以下兩種方式獲取:

 

              傳入id值           context.getBeans("person");

 

              傳入class類型  context.getBeans("Person.class");

 

       經過class方式獲取bean時,若是同一個類配置過多個bean,則在獲取時由於沒法肯定到底要獲取哪一個bean會拋出異常。

 

     而id是惟一的,不存在這樣的問題,因此建議你們儘可能使用id獲取bean。

 
        1     @Test
        2     /**
        3      * SpringIOC獲取bean的方式
        4      */
        5     public void  test3(){
        6             /*
        7              <bean id="person" class="cn.tedu.beans.Person"></bean>
        8              */
        9             /*
       10              <bean id="person" class="cn.tedu.beans.Person"></bean>
       11              <bean id="personx" class="cn.tedu.beans.Person"></bean>
       12              */
       13             ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       14             //--經過id獲取
       15             Person p1 = (Person) context.getBean("person");
       16             p1.say();
       17             //--經過class獲取
       18             Person p2 = context.getBean(Person.class);
       19             p2.say();
       20     }
 

5. 別名標籤

       在 Spring中提供了別名標籤<alias>能夠爲配置的<bean>起一個別名,要注意的是這僅僅是對指定的<bean>起的一個額外的名字,並不會額外的建立對象存入map。原來的id仍是能夠用

              <alias name="要起別名的bean的id"  alias="要指定的別名"/>

 
@Test
/**
 * SpringIOC中bean別名
 */
public void  test4(){
        /*
                <bean id="person" class="cn.tedu.beans.Person"></bean>
                <alias name="person" alias="personx"/>        
         */
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //--經過id獲取
        Person p1 = (Person) context.getBean("personx");
        p1.say();
}
 

6. Spring建立對象的方式

       a. 經過類的沒法構造方法建立對象

              在入門案例中使用的就是這種方式。當用最普通方式配置一個<bean>時,默認就是採用類的無參構造建立對象。在Spring容器初始化時,經過<bean>上配置的class屬性反射獲得字節碼對象,經過newInstance()建立對象

         

                   Class c = Class .forName("類的全路徑名稱")
                   Object obj = c.newInstance()

 

              這種方式下spring建立對象,要求類必須有無參的構造,不然沒法經過反射建立對象,會拋出異常。

                      

package cn.tedu.beans;

public class Person {
    public Person(String arg) {
        System.out.println("Person的無參構造執行了。。。");
    }
    public void say(){
        System.out.println("person hello spring~");
    }
}

/**
* 若是bean不存在無參構造 ,則經過默認反射方式沒法建立對象,Spring容器初始化時會拋出異常
* <bean id="person" class="cn.tedu.domain.Person"/>
*/
@Test
public void test01(){
//1.初始化Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.基於Spring容器建立對象
Person p1 = (Person) context.getBean("person");
//3.測試
System.out.println(p1);

 

會引起異常

 

       b. 經過靜態工廠建立對象

             不少的時候,咱們面對的類是沒法經過無參構造去建立的,例如該類沒有無參構造、是一抽象類 等等狀況 ,此時沒法要求spring經過無參構造建立對象,此時可使用靜態工廠 方式建立對象。

             

package cn.tedu.factory;

import cn.tedu.domain.Person;

public class PersonStaticFactory {
    public static Person getPerson(){
        Person p = new Person("zs");
        return p;
    }
}

測試

    /**
     * 靜態工廠
       <bean id="person" 
        class="cn.tedu.factory.PersonStaticFactory" 
        factory-method="getPerson"/>       factory-method 指明獲取到對象的方法
     */
    @Test
    public void test02(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.獲取bean
        Person p = (Person) context.getBean("person");
        //3.測試
        p.eat();
        p.say();
    }

配置文件

<bean id="person" class="cn.tedu.factory.PersonStaticFactory" factory-method="getPerson"/> 

 

       c. 實例工廠建立對象

              實例工廠也能夠解決類是沒法經過無參構造建立的問題,解決的思路和靜態 工廠相似,只不過實例工廠提供的方法不是靜態的。spring須要先建立出實例工廠的對象,在調用實例工廠對象上指定的普通方法來建立對象。因此實例工廠也須要配置到Spring中管理。

       

package cn.tedu.factory;

import cn.tedu.domain.Person;

public class PersonInstanceFactory {
    public Person getPerson(){
        Person p = new Person("zs");
        return p;
    }
}
    @Test
    public void test03(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.獲取bean
        Person p = (Person) context.getBean("person");
        //3.測試
        p.eat();
        p.say();
    }

配置文件

<bean id="pifactory" class="cn.tedu.factory.PersonInstanceFactory"  />     //先建立一個工廠類對象,經過對象調用裏面的非靜態方法
    <bean id="person" factory-bean="pifactory" factory-method="getPerson"/>  //要建立的對象,factory-bean 指代的是採用哪一個工廠類對象,factory-method 對象調用的方法
 

 

       d. Spring工廠建立對象

              Spring內置了工廠接口,也能夠經過實現這個接口來開發Spring工廠,經過這個工廠建立對象。

package cn.tedu.factory;

import org.springframework.beans.factory.FactoryBean;

import cn.tedu.domain.Person;

public class PersonSpringFactory implements FactoryBean<Person> { //首先要實現FactoryBean接口 裏面的泛型規定的是實際產生的對象

    /**
     * 獲取bean
     */
    public Person getObject() throws Exception {
        return new Person("zs");
    }

    /**
     * 獲取bean的類型
     */
    public Class<?> getObjectType() {
        return Person.class;
    }

    /**
     * 肯定對象是不是單例的
     */
    public boolean isSingleton() {
        return true;
    }

}
    @Test
    public void test04(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.獲取bean
        Person p = (Person) context.getBean("person"); //返回的是object類型
        //3.測試
        p.eat();
        p.say();
    }
<bean id="person" class="cn.tedu.factory.PersonSpringFactory"/>

 

               

7. 單例和多例

       Spring容器管理的bean在默認狀況下是單例的,也即,一個bean只會建立一個對象,存在內置 map中,以後不管獲取多少次該bean,都返回同一個對象。

       Spring默認採用單例方式,減小了對象的建立,從而減小了內存的消耗。

       可是在實際開發中是存在多例的需求的,Spring也提供了選項能夠將bean設置爲多例模式。

    

public class Test01 {
    public static void main(String[] args) {
        new Test01().test01();
    }
    
    
    /**
     * Spring容器默認 單例 方式管理bean
     * 能夠經過配置bean的scope屬性來控制 單例/多例
        <!-- 
        bean的scope屬性:
            singleton:單例方式管理bean,默認就是單例
            prototype:多例方式管理bean
        -->
        <bean id="person" class="cn.tedu.domain.Person" scope="prototype"/>
     */
    @Test
    public void test01(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基於Spring容器建立對象 
        Person p1 = (Person) context.getBean("person");
        Person p2 = (Person) context.getBean("person");
        //3.測試
        System.out.println(p1); //單例的話地址值一致,多例不一致
        System.out.println(p2);
    }
    
}

配置文件

<?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-3.2.xsd ">
    
    <!-- 
        bean的scope屬性:
            singleton:單例方式管理bean,默認就是單例
            prototype:多例方式管理bean
     -->
    <bean id="person" class="cn.tedu.domain.Person" scope="prototype"/>
</beans>

       bean在單例模式下的生命週期:

              bean在單例模式下,spring容器啓動時解析xml發現該bean標籤後,直接建立該bean的對象存入內部map中保存,此後不管調用多少次getBean()獲取該bean都是從map中獲取該對象返回,一直是一個對象。此對象一直被Spring容器持有,直到容器退出時,隨着容器的退出對象被銷燬。

      

       bean在多例模式下的生命週期:

              bean在多例模式下,spring容器啓動時解析xml發現該bean標籤後,只是將該bean進行管理,並不會建立對象,此後每次使用 getBean()獲取該bean時,spring都會從新建立該對象返回,每次都是一個新的對象。這個對象spring容器並不會持有,什麼銷燬取決於使用該對象的用戶本身何時銷燬該對象。

 

8. 懶加載機制

       Spring默認會在容器初始化的過程當中,解析xml,並將單例的bean建立並保存到map中,這樣的機制在bean比較少時問題不大,但一旦bean很是多時,spring須要在啓動的過程當中花費大量的時間來建立bean 花費大量的空間存儲bean,但這些bean可能好久都用不上,這種在啓動時在時間和空間上的浪費顯得很是的不值得。

       因此Spring提供了懶加載機制。所謂的懶加載機制就是能夠規定指定的bean不在啓動時當即建立,而是在後續第一次用到時才建立並將對象放入map中,從而減輕在啓動過程當中對時間和內存的消耗。

       懶加載機制只對單例bean有做用,對於多例bean設置懶加載沒有意義。

      

       懶加載的配置方式:    

<?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-3.2.xsd "
    default-lazy-init="true" //爲全局bean配置懶加載機制
    >
    <bean id="person" class="cn.tedu.domain.Person" lazy-init="true"/> //   爲指定bean配置懶加載
</beans>

              **若是同時設定全局和指定bean的懶加載機制,且配置不相同,則對於該bean局部配置覆蓋全局配置。           

9. 配置初始化和銷燬的方法

       在Spring中若是某個bean在初始化以後 或 銷燬以前要作一些 額外操做能夠爲該bean配置初始化和銷燬的方法 ,在這些方法中完成要功能。

      

public class Person{
    public Person() {
        System.out.println("Person建立了..");
    }
    public void personInit(){
        System.out.println("初始化Person...");
    }
    public void personDestory(){
        System.out.println("銷燬Person...");
    }
    public void eat(){
        System.out.println("吃...");
    }
    public void say(){
        System.out.println("說...");
    }
}

 

public class Test01 {
    public static void main(String[] args) {
        new Test01().test01();
    }
    
    
    /**
     * 初始化 和 銷燬 方法
     */
    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基於Spring容器建立對象 
        Person p1 = (Person) context.getBean("person");
        //3.測試
        System.out.println(p1);
        //4.關閉容器
        context.close(); //ApplicationContext接口沒有close方法,他的實現類    ClassPathXmlApplicationContext 有這個方法
    }
    
}

配置文件

  

<?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-3.2.xsd "
    >
    
    <bean id="person" class="cn.tedu.domain.Person"
        init-method="personInit"           //對象初始化的方法
        destroy-method="personDestory"       //對象銷燬時的方法
    />
    
</beans>

    **Spring中關鍵方法的執行順序:

              在Spring建立bean對象時,先建立對象(經過無參構造或工廠),以後當即調用init方法來執行初始化操做,以後此bean就能夠哪來調用其它普通方法,而在對象銷燬以前,spring容器調用其destory方法來執行銷燬操做。

二。DI 依賴注入

 

1. IOC(DI) - 控制反轉(依賴注入)

       所謂的IOC稱之爲控制反轉,簡單來講就是將對象的建立的權利及對象的生命週期的管理過程交由Spring框架來處理,今後在開發過程當中再也不須要關注對象的建立和生命週期的管理,而是在須要時由Spring框架提供,這個由spring框架管理對象建立和生命週期的機制稱之爲控制反轉。而在 建立對象的過程當中Spring能夠依據配置對對象的屬性進行設置,這個過稱之爲依賴注入,也即DI。

2. set方法注入

       一般的javabean屬性都會私有化,而對外暴露setXxx()getXxx()方法,此時spring能夠經過這樣的setXxx()方法將屬性的值注入對象。 

      

       a. Spring普通屬性注入:

首先是Person javaBean類
package cn.tedu.domain;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;


public class Person{
    private int id;
    private String name;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties prop;
    private Dog dog;  //屬性中包含其餘對象 private Cat cat;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Set<String> getSet() {
        return set;
    }
    public void setSet(Set<String> set) {
        this.set = set;
    }
    public Map<String, String> getMap() {
        return map;
    }
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    public Properties getProp() {
        return prop;
    }
    public void setProp(Properties prop) {
        this.prop = prop;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
    public Cat getCat() {
        return cat;
    }
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", list=" + list
                + ", set=" + set + ", map=" + map + ", prop=" + prop + ", dog="
                + dog + ", cat=" + cat + "]";
    }
}
 

Dog類 和Cat類

package cn.tedu.domain;

public class Dog {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Dog [name=" + name + ", age=" + age + "]";
    }
}
package cn.tedu.domain;

public class Cat {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age + "]";
    }
}

 

配置文件中的屬性注入

<?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-3.2.xsd "
    >
    
    <bean id="person" class="cn.tedu.domain.Person">
        <property name="id" value="99"></property>
        <property name="name" value="亞瑟"></property>
        <property name="list">
            <list>
                <value>上單</value>
                <value>下單</value>
                <value>打野</value>
                <value>中單</value>
                <value>輔助</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>s1</value>
                <value>s2</value>
                <value>s3</value>
                <value>s2</value>
                <value>s4</value>
                <value>s5</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="k1" value="v1"></entry>
                <entry key="k2" value="v2"></entry>
                <entry key="k3" value="v3"></entry>
                <entry key="k2" value="v22"></entry>
            </map>
        </property>
        <property name="prop">
            <props>
                <prop key="p1">v1</prop>
                <prop key="p2">v2</prop>
                <prop key="p3">v3</prop>
            </props>
        </property>
        <property name="dog" ref="dog"></property>   
        <property name="cat" ref="cat"></property>
    </bean>
    <bean id="dog" class="cn.tedu.domain.Dog">
        <property name="name" value="旺財"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean id="cat" class="cn.tedu.domain.Cat">
        <property name="name" value="湯姆"></property>
        <property name="age" value="5"></property>
    </bean>
</beans>

要先建立屬性對象的bean。

在這裏要申明一點的是:<property name="age" value="5"></property>  中name的值即age,這是一個javaBean屬性即Person javabean中SetXxx()方法的後三個單詞xxx,而不是Person中的age成員屬性,就好比把age的setAge(int age)方法改爲

setAgebbb(int age) ,那麼要改爲<property name="agebbb" value="5"></property>

    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基於Spring容器建立對象 
        Person p1 = (Person) context.getBean("person");
        //3.測試
        System.out.println(p1);
        //4.關閉容器
        context.close();
    }
    
 

自動裝配---支持的是bean對象的注入

 

       在Spring的set方式實現的注入過程當中,支持自動裝配機制,所謂自動裝配機制,會根據要設置的javabean屬性的名字 或 類型 到spring中自動尋找對應id 或 類型的<bean>進行設置,從而 省去依次配置的過程,簡化了配置。

 

       爲 指定<bean>開啓自動裝配:

<?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-3.2.xsd "
    default-autowire="byName"  全局自動裝配
> <!-- autowire自動裝配: byName: 根據要注入的屬性名尋找同id的bean進行注入 若是找不到不報錯也不注入 byType: 根據要注入的屬性類型尋找同類型的bean進行注入 若是存在多個該類型的bean則報錯

   **byType方式 根據類型進行匹配,可能匹配到多個<bean>,此時會拋出異常。而byName是經過id來尋找<bean>,id沒有重複,不會有這方面的問題,因此推薦使用byName方式

-->
    <bean id="person" class="cn.tedu.domain.Person" autowire="byType">  局部自動裝配
        <!-- 
        <property name="dog" ref="dog"></property>
        <property name="cat" ref="cat"></property> 
        -->
    </bean>
    <bean id="dogx" class="cn.tedu.domain.Dog">
        <property name="name" value="旺財"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean id="catx" class="cn.tedu.domain.Cat">
        <property name="name" value="湯姆"></property>
        <property name="age" value="5"></property>
    </bean>
</beans>

 Person類  

package cn.tedu.domain;

public class Person{
    private Dog dog;
    private Cat cat;
    
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    public Cat getCat() {
        return cat;
    }
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    @Override
    public String toString() {
        return "Person [dog=" + dog + ", cat=" + cat + "]";
    }
    
}

測試

public class Test01 {
    public static void main(String[] args) {
        new Test01().test01();
    }
    
    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基於Spring容器建立對象 
        Person p1 = (Person) context.getBean("person");
        //3.測試
        System.out.println(p1);
        //4.關閉容器
        context.close();
    }
    
}

4. 基於構造方法的注入

     對象屬性設置的另外一種方式是在對象建立的過程當中經過構造方法傳入並設置對象的屬性。spring也能夠經過這樣的構造方法實現屬性的注入

 測試

    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基於Spring容器建立對象 
        Person p1 = (Person) context.getBean("person");
        //3.測試
        System.out.println(p1);
        //4.關閉容器
        context.close();
    }
<?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-3.2.xsd "
    >
    <bean id="person" class="cn.tedu.domain.Person">
        <!--
            構造方法方式實現屬性注入:
                經過<constructor-arg>能夠實現bean的構造方法方式實現注入
                其中的屬性:
                    name:限定要爲哪一個名字的構造方法參數注入
                    index: 爲哪一個索引位的構造方法參數注入
                    type: 當前注入的參數的類型
                    value: 要爲當前參數設定什麼值,若是是非自定義bean類型,使用此屬性注入
                    ref: 要爲當前參數設定哪一個自定義bean,若是是自定義bean類型,使用此屬性注入
        
        -->
        <!-- 
        <constructor-arg name="name" value="zs"></constructor-arg>
        <constructor-arg name="age" value="19"></constructor-arg>
         -->
         <constructor-arg index="0"  value="zs"></constructor-arg>
         <constructor-arg index="1"  value="19"></constructor-arg>
         <constructor-arg index="2" ref="dog"></constructor-arg>
         <constructor-arg index="3" ref="cat"></constructor-arg>
    </bean>
    <bean id="dog" class="cn.tedu.domain.Dog">
        <property name="name" value="旺財"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean id="cat" class="cn.tedu.domain.Cat">
        <property name="name" value="湯姆"></property>
        <property name="age" value="5"></property>
    </bean>
</beans>

一般使用index進行參數注入,由於你一般用的是別人的jar包,沒有源代碼的狀況下,你只能知道參數的個數,以及參數的類型,沒法得到參數名。因此這就致使了有些方法你調用的時候參數部分是arg0,arg1,arg2

相關文章
相關標籤/搜索