spring--設置注入VS構造注入

一、在傳統的程序設計中,調用親自建立被調用者的實例,即由程序控制「對象之間的依賴關係」,這種方式的耦合度比較高;控制反轉就是將由程序控制的「對象間的依賴關係」轉交給Ioc容器來進行控制,被調用者的實例建立工做再也不是調用者完成, 大大下降了調用者和被調用者之間的關係。Ioc(inversion of control:控制反轉)和Di(dependency Injection:依賴注入) 是相同的概念。

  

二、實現依賴注入的方式:
2.一、屬性注入:
 //bean類  被關聯
    package com.liu.spring;
    public class RefBean {
        private String meg;
        public String getMeg() {
            return meg;
        }
        public void setMeg(String meg) {
            this.meg = meg;
        }
    }
    //bean 將關聯RefBean類
    package com.liu.spring;
    public class MessageBean {
        private String message;
        private RefBean refBean;//關聯的RefBean類
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public RefBean getRefBean() {
            return refBean;
        }
        public void setRefBean(RefBean refBean) {
            this.refBean = refBean;
        }
    }
  //配置文件
    <beans>
        <!-- 配置文件 1.先配置類爲RefBean -->
        <bean id="refBean" class="com.liu.spring.RefBean">
            <property name="meg">
                <value>我是屬性注入方式實現的(我在RefBean類中)</value>
            </property>
        </bean>
        <!-- 二、再來配置類 MessageBean  -->
        <bean id="messageBean" class="com.liu.spring.MessageBean">
            <property name="message">
                <value>Spring框架(我是在MessageBean類中)</value>
            </property>
            <!-- 加入另外一個bean  -->
            <property name="refBean">
                <ref local="refBean"/>
            </property>
        </bean>
    </beans>
  //測試類
    package com.liu.action;
    public class Action_01 {    
        public static void main(String[] args) {
            //加載配置文件
            ClassPathResource resource=new ClassPathResource("applicationContext.xml");
            //建立bean工廠
            BeanFactory factory=new XmlBeanFactory(resource);
            //獲取對用的實例(就避免的new對象)
            MessageBean message=(MessageBean) factory.getBean("messageBean");
            //打印結果
            System.out.println(message.getMessage()+","+message.getRefBean().getMeg());
        }
    }
    //最終的結果是
    Spring框架(我是在MessageBean類中),我是屬性注入方式實現的(我在RefBean類中)

  

2.二、構造方法注入:
注:只需在被關聯的類中寫好構造函數,在配置文件之中寫好配置文件就行
    //配置文件寫法
     <bean id="messageBean" class="com.liu.spring.MessageBean">
         <!--- 構造函數注入的關鍵標籤 --->
         <constructor-arg index="0">
             <value>Spring框架(我是在MessageBean類中)</value>
         </constructor-arg>
         <constructor-arg index="1">
             <!-- 引用以外的bean  -->
             <ref local="refBean"/>
         </constructor-arg>
     </bean>
     <!-- 被關聯的bean類--->
     <bean id="refBean" class="com.liu.spring.RefBean">
        <property name="meg">
            <value>我是屬性注入方式實現的(我在RefBean類中)</value>
        </property>
    </bean>    
2.三、構造注入須知:
    爲了不如今的配置文件的歧義而引發的張冠李戴,在bean中存在多個構造函數時,使用顯示指定index和type屬性
    比較直觀。
2.四、屬性注入和構造注入的比較:
    2.4.一、屬性注入的特色是不須要知道屬性的類型,可是必須知道屬性的名稱;使用set()方法實現依賴注入
    2.4.二、構造函數注入的特色是不須要知道參數的名稱,不須要知道set(),可是必須知道參數的序號和類型,必須定義包含不一樣參數
                的構造函數。
    2.4.三、構造函數注入和屬性注入方式各有優缺點。
三、循環依賴問題:
    3.一、什麼是循環依賴:
                    spring容器可以順利實例化以構造函數注入的方式配置的Bean有一個前提:Bean引用的構造函數入參引用的對象必須已近準備就緒。因爲這種機制,若是兩個bean都採用構造函數注入,並且都是經過構造函數入參引用對方,就會發生死鎖,就是依賴循環。

          實體類以下:
//Boss類
        package com.liu.spring;
        public class Boss {    
            private String name;
            private Car car;
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public Car getCar() {
                return car;
            }
            public void setCar(Car car) {
                this.car = car;
            }
            //構造函數
            public Boss(String name, Car car) {
                super();
                this.name = name;
                this.car = car;
            }
        }
        //car類
        package com.liu.spring;
        public class Car {
            private String brand;
            private Boss boss;
            public String getBrand() {
                return brand;
            }
            public void setBrand(String brand) {
                this.brand = brand;
            }
            public Boss getBoss() {
                return boss;
            }
            public void setBoss(Boss boss) {
                this.boss = boss;
            }
            //構造函數
            public Car(String brand, Boss boss) {
                super();
                this.brand = brand;
                this.boss = boss;
            }
        }
   //配置文件
        <!-- 循環依賴問題的配置文件以下 (錯) -->
        <bean id="car" class="com.liu.spring.Car"><!-- car類 -->
            <constructor-arg>
                <value>我是勞斯萊斯(來之car類)</value>
            </constructor-arg>
            <constructor-arg>
                <ref local="boss"/><!-- 引用boss -->
            </constructor-arg>
        </bean>
        <bean id="boss" class="com.liu.spring.Boss">
            <constructor-arg>
                <value>我是劉明(來之boss類)</value>
            </constructor-arg>
            <constructor-arg>
                <ref local="car"/><!-- 引用car -->
            </constructor-arg>
        </bean>
        異常爲:Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
    3.二、循環依賴解決方法(配置文件使用屬性注入)
 <!-- 循環依賴問題的配置文件以下 (正確) -->
        <bean id="car" class="com.liu.spring.Car">
            <property name="brand">
                <value>我是勞斯拉斯(來之car類)</value>
            </property>
            <property name="boss">
                <ref local="boss"/>
            </property>
        </bean>
        <bean id="boss" class="com.liu.spring.Boss">
            <property name="name">
                <value>我是不知道(來之boss類)</value>
            </property>
            <property name="car">
                <ref local="car"/>
            </property>
        </bean>
        ------測試類------------------
        //加載配置文件
        ClassPathResource resource=new ClassPathResource("applicationContext.xml");
        //建立bean工廠
        BeanFactory factory=new XmlBeanFactory(resource);
        //得到對應的實體類
        Car car=(Car) factory.getBean("car");
        Boss boss=(Boss) factory.getBean("boss");
        System.out.println(car.getBrand()+"========"+car.getBoss().getName());
        System.out.println(boss.getName()+"======="+boss.getCar().getBrand());
        最後的結果是:
        我是勞斯拉斯(來之car類)========我是不知道(來之boss類)
        我是不知道(來之boss類)=======我是勞斯拉斯(來之car類)
相關文章
相關標籤/搜索