Spring-02-依赖注入DI

五、依赖注入——DI

5.1 Setter注入(最常用)

  • 实体类

    public class Address {
        private String province;
        private String city;
        private String district;
    }
    
    public class People {
        private String name;
        private Address address;
        private String[] cars;
        private List<String> phones;
        private Map<String, String> relationship;
        private Set<String> vips;
        private String wife;
        private Properties info;
    }
    
  • beans.xml配置

    <bean id="address" class="com.pbx.pojo.Address">
      <property name="province" value="浙江省"/>
      <property name="city" value="杭州市"/>
      <property name="district" value="西湖区"/>
    </bean>
    
    <bean id="bruce" class="com.pbx.pojo.People">
      <!--常规注入-->
      <property name="name" value="BruceXu" />
        
      <!--引用Bean进行注入-->
      <property name="address" ref="address"/>
        
      <!--注入数组-->
      <property name="cars">
          <array>
              <value>奔驰</value>
              <value>奥迪</value>
              <value>宝马</value>
          </array>
      </property>
        
      <!--注入List-->
      <property name="phones">
          <list>
              <value>iphone</value>
              <value>华为</value>
              <value>小米</value>
          </list>
      </property>
        
      <!--注入Map-->
      <property name="relationship">
          <map>
              <entry key="老板" value="马云"/>
              <entry key="二次元老婆" value="蕾姆"/>
          </map>
      </property>
        
      <!--注入Set-->
      <property name="vips">
          <set>
              <value>爱奇艺</value>
              <value>腾讯视频</value>
              <value>芒果tv</value>
          </set>
      </property>
        
      <!--注入空指针-->
      <property name="wife">
          <null/>
      </property>
        
      <!--注入Properties-->
      <property name="info">
          <props>
              <prop key="手机号">11122223333</prop>
              <prop key="身份证号">111111222222223333</prop>
          </props>
      </property>
        
    </bean>
    
  • 测试

    package com.pbx;
    
    import com.pbx.pojo.People;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author BruceXu
     * @date 2020/11/17
     */
    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            People people = (People) context.getBean("bruce");
            System.out.println(people);
        }
    }
    

    image-20201117213638275

5.2 构造器注入

  • 实体类

    public class Student {
        private int id;
        private String name;
        private String garde;
        
        public Student(int id, String name, String garde) {
            this.id = id;
            this.name = name;
            this.garde = garde;
        }
    }
    
  • beans.xml

    <!--通过构造器参数下标注入-->
    <bean id="student1" class="com.pbx.pojo.Student">
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="张三"/>
        <constructor-arg index="2" value="一年级"/>
    </bean>
    
    <!--通过构造器形参名称注入-->
    <bean id="student2" class="com.pbx.pojo.Student">
        <constructor-arg name="id" value="2"/>
        <constructor-arg name="name" value="李四"/>
        <constructor-arg name="garde" value="二年级"/>
    </bean>
    
    <!--通过参数类型注入-->
    <bean id="student3" class="com.pbx.pojo.Student">
        <constructor-arg type="int" value="3"/>
        <constructor-arg type="java.lang.String" value="王五"/>
        <constructor-arg type="java.lang.String" value="三年级"/>
    </bean>
    
    <bean id="student4" class="com.pbx.pojo.Student">
        <constructor-arg type="int" value="3"/>
        <constructor-arg type="java.lang.String" value="四年级"/>
        <constructor-arg type="java.lang.String" value="赵六"/>
    </bean>
    
  • 测试

    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student1");
        System.out.println(student);
        System.out.println("==============");
        student = (Student) context.getBean("student2");
        System.out.println(student);
        System.out.println("==============");
        student = (Student) context.getBean("student3");
        System.out.println(student);
        System.out.println("==============");
        student = (Student) context.getBean("student4");
        System.out.println(student);
    }
    

    image-20201117214749189

5.3 命名空间注入

  • 命名空间注入的方式可以简化Spring配置文件的编写,适用于简单类型属性的注入

  • 实体类

    public class User {
        private int id;
        private String name;
        private Address address;
    }
    
  • user.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"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:c="http://www.springframework.org/schema/c"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="user1" class="com.pbx.pojo.User" p:id="1" p:name="张三"/>
        <bean id="user2" class="com.pbx.pojo.User" c:id="2" c:name="李四"/>
        
    </beans>
    
  • 测试

    @Test
    public void test2() {
        ApplicationContext context = new ClassPathXmlApplicationContext("user.xml");
        User user1 = context.getBean("user1", User.class);
        System.out.println(user1);
        User user2 = context.getBean("user2", User.class);
        System.out.println(user2);
    }
    

  • 注意

    • 要使用命名空间注入,需要导入命名空间的约束文件

      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:c="http://www.springframework.org/schema/c"
      
    • p命名空间和c命名空间实际上是代表标签 <property><constructor-arg>

5.4 自动装配

  • Spring可以不用显式的配置bean的property属性,通过自动装配也可以完成Bean的注入

  • Spring‘的自动装配机制主要依赖两个操作

    • 组件扫描:Spring会扫描被容器中的bean
    • 自动装配:Spring会根据某些条件来自动装配那些设置了自动装配的Bean
  • 常见的自动装配方式

    • byName
      • Spring会自动寻找和bean中属性名同名的bean进行装配
    • byType
      • Spring会自动寻找和bean中属性类型相同的bean进行装配。如果有多个类型相同的bean,那么要报错
  • 环境搭建

    • 实体类

      public class People {
          private String name;
          private Dog dog;
          private Cat cat;
      }
      
      public class Cat implements Pet {
          @Override
          public void shout() {
              System.out.println("Cat::shout()");
          }
      }
      
      public class Dog implements Pet {
          @Override
          public void shout() {
              System.out.println("Dog::shout()");
          }
      }
      
    • beans.xml

      <bean id="cat" class="com.pbx.pojo.Cat"/>
      <bean id="dog" class="com.pbx.pojo.Dog"/>
      
      <bean id="p1" class="com.pbx.pojo.People" autowire="byName">
      </bean>
      
      <bean id="p2" class="com.pbx.pojo.People" autowire="byType">
      </bean>
      
  • 测试

    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        People p1 = context.getBean("p1", People.class);
        People p2 = context.getBean("p2", People.class);
    
        p1.show();
        System.out.println("================");
        p2.show();
    
    }
    

    image-20201118151726467

posted @ 2020-11-21 16:16  PrimaBruceXu  阅读(68)  评论(0编辑  收藏  举报