什么是IOC

IOC全称是Inversion of Control(管制反转),所谓管制反转是对于程序自身而言,以前咱们在创建对象的时候是本人通过new创立进去,而当初咱们把这个势力交给了Spring去做,让它帮咱们去创建对象和治理对象,对对象的控制权反转给了Spring

什么是DI

DI全称是Dependency Injection(依赖注入),所谓依赖注入是对于Spring的IOC容器而言,以前咱们在给对象的属性赋值时有两种渠道,一种是通过带参数的构造方法,另一种是通过set办法。而当初IOC容器在创建对象的同时把属性的值注入进去。
什么是依赖:比方A对象的属性里有B对象,那么就叫A依赖B

Spring的DI实例

  • 依赖注入有两种形式,一种是基于对象的构造函数,另一种是基于对象属性对象的set办法,根本实现思路是这样的:

    • 基于构造函数: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转换成对应的数据类型

  • 注入聚合对象

    • 如果是对象外面套了另一个对象,有两种写法,一种是在bean外面配置一个bean,另一种是在bean外面引入一个内部bean
    • 第一种写法

      /* 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>
    • 第二种写法

      • 通过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>
  • 注入汇合

    • 注入List、set、map、properties汇合
//TestCollection.javapackage 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:不反对主动拆卸性能