Spring--IOC、DI、自動裝配

什麼是IOC

IOC全稱是Inversion of Control(控制反轉),所謂控制反轉是對於程序自己而言,之前咱們在建立對象的時候是本身經過new建立出來,而如今咱們把這個權力交給了Spring去作,讓它幫咱們去建立對象和管理對象,對對象的控制權反轉給了Springjava

什麼是DI

DI全稱是Dependency Injection(依賴注入),所謂依賴注入是對於Spring的IOC容器而言,之前咱們在給對象的屬性賦值時有兩種渠道,一種是經過帶參數的構造方法,另外一種是經過set方法。而如今IOC容器在建立對象的同時把屬性的值注入進去。
什麼是依賴:好比A對象的屬性裏有B對象,那麼就叫A依賴Bspring

Spring的DI實例

  • 依賴注入有兩種方式,一種是基於對象的構造函數,另外一種是基於對象屬性對象的set方法,基本實現思路是這樣的:dom

    • 基於構造函數:Spring參考bean配置,提取出bean對象的參數,經過構造方法實例化bean對象
    • 基於屬性的set方
    • 法:Spring參考bean配置,首先先經過無參的構造方法實例化bean對象,而後經過set方法設置bean對象的屬性
  • 注入基本數據類型(8大基本數據類+String)
/* User.java */
public class User {
     private String account;
     private String password;
     private Float balance;
     public User(String account, String password, Float balance) {
            this.account = account;
     this.password = password;
     this.balance = balance;
     }
        public User(){
            System.out.println("User對象建立了");
     }
        @Override
     public String toString() {
            return "User{" +
                    "account='" + account + ''' +
                    ", password='" + password + ''' +
                    ", balance=" + balance +
                    '}';
     }
        public String getAccount() {
            System.out.println("set方法調用了");
     return account;
     }
        public void setAccount(String account) {
            this.account = account;
     }
        public String getPassword() {
            return password;
     }
        public void setPassword(String password) {
            this.password = password;
     }
        public Float getBalance() {
            return balance;
     }
        public void setBalance(Float balance) {
            this.balance = balance;
     }
}
/* main函數 */
public class TestMain {
    public static void main(String[] args) {
         System.out.println(userDao.selectUserByAccount("2018"));
         AbstractApplicationContext factory = new ClassPathXmlApplicationContext("ApplicationContext.xml");
         User user = (User) factory.getBean("user");
         System.out.println(user);
     }
}
<!-- 配置文件-->
<?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
 https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="user" class="com.cjh.domain.User">
         <property name="account" value="2019"></property>
         <property name="password" value="123"></property>
         <property name="balance" value="777"></property>
     </bean>
</beans>

若是是基本數據類型/String的話,直接經過value寫入要傳遞的值,底層會根據屬性的具體類型將value轉換成對應的數據類型ide

  • 注入聚合對象函數

    • 若是是對象裏面套了另外一個對象,有兩種寫法,一種是在bean裏面配置一個bean,另外一種是在bean裏面引入一個外部bean
    • 第一種寫法this

      /* person.java */
      public class Person {
           private String name;
           //引入了上面的user對象
           private User user;
           public Person(){}
              @Override
           public String toString() {
                  return "Person{" +
                          "name='" + name + ''' +
                          ", user=" + user +
                          '}';
           }
              public String getName() {
                  return name;
           }
              public void setName(String name) {
                  this.name = name;
           }
              public User getUser() {
                  return user;
           }
              public void setUser(User user) {
                  this.user = user;
           }
      }
      //主函數
      public class TestMain {
           public static void main(String[] args) {  
                   System.out.println(userDao.selectUserByAccount("2018"));
                   ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
                   Person person = (Person) context.getBean("person");
                   System.out.println(person);
           }
      }
      <!-- 配置文件 -->
      <?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
       https://www.springframework.org/schema/beans/spring-beans.xsd">
           <bean id="person" class="com.cjh.domain.Person">
               <property name="name" value="john"></property>
               <property name="user">
                   <bean id="user" class="com.cjh.domain.User">
                       <property name="account" value="2019"></property>
                       <property name="password" value="123"></property>
                       <property name="balance" value="777"></property>
                   </bean>
               </property> 
           </bean>
      </beans>
    • 第二種寫法code

      • 經過property標籤中的ref屬性引入一個外部變量
<!-- 配置文件 -->
<?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
 https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="person" class="com.cjh.domain.Person">
         <property name="name" value="john"></property>
         <property name="user" ref="user"></property>
     </bean>
     <bean id="user" class="com.cjh.domain.User">
         <property name="account" value="2019"></property>
         <property name="password" value="123"></property>
         <property name="balance" value="777"></property>
     </bean>
</beans>
  • 注入集合xml

    • 注入List、set、map、properties集合
//TestCollection.java
package com.cjh.domain;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class TestCollection {
     private List<String> list;
     private Set<String> set;
     private Map<Integer, String> map;
     private Properties properties;
     public TestCollection(){}
        @Override
     public String toString() {
            return "TestCollection{" +
                    "list=" + list +
                    ", set=" + set +
                    ", map=" + map +
                    ", properties=" + properties +
                    '}';
     }
        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<Integer, String> getMap() {
            return map;
     }
        public void setMap(Map<Integer, String> map) {
            this.map = map;
     }
        public Properties getProperties() {
            return properties;
     }
        public void setProperties(Properties properties) {
            this.properties = properties;
     }
    }
//主函數
public class TestMain {
    public static void main(String[] args) {
      System.out.println(userDao.selectUserByAccount("2018"));
     ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
     TestCollection collection = (TestCollection) context.getBean("testCollection");
     System.out.println(collection);
     }
}
<!-- 配置信息 -->
<?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
 https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="testCollection" class="com.cjh.domain.TestCollection">
         <property name="list">
             <list value-type="java.lang.String">
                 <value>12</value>
                 <value>13</value>
                 <value>14</value>
                 <value>15</value>
             </list> 
         </property> 
         <property name="set">
             <set value-type="java.lang.String">
                 <value>abc</value>
                 <value>def</value>
                 <value>ghi</value>
                 <value>jkl</value>
                 <value>mno</value>
             </set> 
         </property> 
         <property name="map">
             <map key-type="java.lang.Integer" value-type="java.lang.String">
                 <entry key="1" value="a"/>
                 <entry key="2" value="b"/>
                 <entry key="3" value="c"/>
             </map> 
         </property> 
         <property name="properties">
             <props value-type="String">
                 <prop key="a">1</prop>
                 <prop key="b">2</prop>
                 <prop key="c">3</prop>
             </props>
         </property> 
     </bean>
</beans>
  • 注入null和空字符串
<bean id="person" class="com.cjh.domain.Person">
 <property name="name" value=""></property>
 <property name="user">
 <null></null> </property></bean>

如上的配置中,value什麼都不給就默認爲""空串,若是須要注入null,須要使用null標籤,若是直接用value="null",Spring會把它解析成字符串null對象

自動裝配

  • byName:在獲取當前bean對象的時候,會根據當前對象的屬性名,在配置文件下找到id/name屬性與之同樣的bean對象,裝配給當前bean對象(經過屬性的set方法)接口

    • 注意:這裏我本身手動試過,當屬性名與bean標籤的name/id名不一致,可是set方法(set方法的命名規則:set+屬性名)的屬性名與name/id一致,也是能夠裝配成功的
    • 因此我得出:Spring是根據set方法的後綴屬性名字與bean標籤中的name/id匹配(我的意見)
  • byType:在獲取當前bean對象的時候,根據當前對象屬性的類型,在配置文件下找到相同類型的bean對象,並裝配給當前bean對象(經過屬性的set方法)

    • 若是beans下存在多個相同類型的bean對象,那麼會報錯
    • 若是當前bean對象的屬性類型是接口、抽象類或者普通類的父類,有三種狀況

      • 當屬性對應的set方法的參數也是上述三種類型,若是beans下只有一個與之匹配的可實例化類型(子類/普通類的父類),那麼裝配成功
      • 當屬性對應的set方法的參數也是上述三種類型,可是beans下有多個與之匹配的可實例化類型,那麼報錯
      • 當屬性對應的set方法的參數是可實例化的類型,而且beans下只有一個與之匹配的類型,裝配成功,若是有多個,那麼報錯
  • constructor:根據帶參的構造方法進行裝配

    • 根據構造方法的參數名和bean標籤的id/name名是否一致
    • 根據構造方法的參數類型和bean標籤的class類型是否一致

      • 若是構造方法的參數類型是父類,那麼beans下要有惟一與之匹配的bean對象(出現多個不裝配)
    • 以上兩點知足其中1點便可裝配
  • no:不支持自動裝配功能
相關文章
相關標籤/搜索