【Spring进阶系列丨第五篇】详解Spring中的依赖注入

文章目录

  • 一、说明
  • 二、构造函数注入
    • 2.1、方式一【index索引方式】
      • 2.1.1、定义Bean
      • 2.1.2、主配置文件中配置Bean
      • 2.1.3、测试
      • 2.2、方式二【index+type组合方式】
        • 2.2.1、定义Bean
        • 2.2.2、主配置文件配置Bean
        • 2.2.3、测试
        • 2.2.4、解决方案
        • 2.3、方式三【name方式】
          • 2.3.1、定义Bean
          • 2.3.2、主配置文件配置Bean
          • 2.3.3、测试
          • 2.4、补充细节
            • 2.4.1、定义Bean
            • 2.4.2、主配置文件配置Bean
            • 2.4.3、测试
            • 2.4.4、解决方案
            • 2.5、总结
            • 三、set方法注入
              • 3.1、定义Bean
              • 3.2、主配置文件配置Bean
              • 3.3、测试
              • 3.4、总结
              • 四、复杂类型的注入
                • 4.1、注入数组类型【array】
                  • 4.1.1、定义Bean
                  • 4.1.2、主配置文件配置Bean
                  • 4.2、注入List类型【list】
                    • 4.2.1、定义Bean
                    • 4.2.2、主配置文件配置Bean
                    • 4.3、注入Set类型【set】
                      • 4.3.1、定义Bean
                      • 4.3.2、主配置文件配置Bean
                      • 4.4、注入Map类型【Map】
                        • 4.4.1、定义Bean
                        • 4.4.2、主配置文件配置Bean
                        • 4.5、注入Properties类型
                          • 4.5.1、定义Bean
                          • 4.5.2、主配置文件配置Bean
                          • 4.6、总结
                          • 好书推荐
                            • 送书活动

                              一、说明

                              • 全称

                                Dependency Injection(DI)

                              • 与IoC的关系

                                IoC和DI其实说的是一个意思,可以这么说:IoC是一种思想,DI是对这种思想的一种具体实现

                                • 依赖关系的管理

                                  以后都交给spring来维护,在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明。

                                  • 依赖关系的维护

                                    ​ 称之为依赖注入。

                                  • 能注入的数据:有三类

                                    ​ 基本类型和String。

                                    ​ 其他bean类型(在配置文件中或者注解配置过的bean)

                                    ​ 复杂类型/集合类型

                                  • 注入的方式:有三种

                                    ​ 第一种:使用构造函数提供

                                    ​ 第二种:使用set方法提供

                                    ​ 第三种:使用注解提供(参考第七章节)

                                    二、构造函数注入

                                    2.1、方式一【index索引方式】

                                    2.1.1、定义Bean

                                    public class Person { private Integer id;
                                        
                                        private String name;	// 姓名
                                        
                                        private Integer age;	// 年龄
                                      
                                      	private Double weight;	// 体重
                                        public Person(Integer id, String name, Integer age) { this.id = id;
                                            this.name = name;
                                            this.age = age;
                                        }
                                    }
                                    

                                    2.1.2、主配置文件中配置Bean

                                         

                                    2.1.3、测试

                                    @Test
                                    public void testPerson() throws Exception{ // 1、读取主配置文件信息,获取核心容器对象
                                        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
                                        Person person = (Person) ac.getBean("person");
                                        System.out.println(person);	// Person{id=1, name='王浩', age=20}
                                    }
                                    

                                    2.2、方式二【index+type组合方式】

                                    说明:案例1采用的index索引的方式实现注入,就以目前案例来说是完全没问题的,但是如果Bean中存在下面情况,可能就不怎么适用了。

                                    需求:我现在要创建Person类的对象,调用Person(Integer id, String name, Double weight)构造方法

                                    2.2.1、定义Bean

                                    说明:为Person类中的weight属性初始化,并专门为其添加构造方法

                                    public class Person { private Integer id;
                                        private String name;    // 姓名
                                        private Integer age;    // 年龄
                                        private Double weight;  // 体重
                                        public Person(Integer id, String name, Integer age) { this.id = id;
                                            this.name = name;
                                            this.age = age;
                                        }
                                      	// 专门为weight属性定义的构造方法
                                        public Person(Integer id, String name, Double weight) { this.id = id;
                                            this.name = name;
                                            this.weight = weight;
                                        }
                                    }
                                    

                                    2.2.2、主配置文件配置Bean

                                         

                                    2.2.3、测试

                                    @Test
                                    public void testPerson() throws Exception{ // 1、读取主配置文件信息,获取核心容器对象
                                        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
                                        Person person = (Person) ac.getBean("person");
                                        System.out.println(person);	// Person{id=1, name='王浩', age=180}
                                    }
                                    

                                    经过测试发现,并不满足我的需求,还是找的是public Person(Integer id, String name, Integer age)构造方法

                                    2.2.4、解决方案

                                    通过type明确指定类型。

                                         

                                    2.3、方式三【name方式】

                                    ​ 前两种方式通过index+type的确可以解决问题,但是总是觉得还是有些麻烦,能否有更加简单的方式呢?就是直接采用参数名的方式更易于阅读和使用。

                                    2.3.1、定义Bean

                                    ​ Bean的定义同2.2.1。

                                    2.3.2、主配置文件配置Bean

                                         

                                    2.3.3、测试

                                    @Test
                                    public void testPerson() throws Exception{ // 1、读取主配置文件信息,获取核心容器对象
                                            ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
                                            Person person = (Person) ac.getBean("person");
                                            System.out.println(person);	// Person{id=1, name='王浩', age=3}
                                    }
                                    

                                    2.4、补充细节

                                    2.4.1、定义Bean

                                    public class Person { private Integer id;
                                        private String name;    // 姓名
                                        
                                        private Date birthday;  // 出生日期
                                        public Person(Integer id, String name, Date birthday) { this.id = id;
                                            this.name = name;
                                            this.birthday = birthday;
                                        }
                                    }
                                    

                                    2.4.2、主配置文件配置Bean

                                         

                                    2.4.3、测试

                                    测试后发现程序报错,原因在于:期望需要一个Date类型,而你现在传了一个字符串,数据类型不匹配。

                                    Unsatisfied dependency expressed through constructor parameter 2: Could not convert argument value of type [java.lang.String] to required type [java.util.Date]
                                    

                                    2.4.4、解决方案

                                            

                                    2.5、总结

                                    • 使用的标签:

                                      ​ constructor-arg

                                    • 标签出现的位置:

                                      ​ bean标签的内部

                                    • 标签中的属性:

                                      ​ type:用于指定要注入的数据的数据类型。

                                      ​ index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引的位置是从0开始。

                                      ​ name:用于指定给构造函数中指定名称的参数赋值。

                                      ​ value:用于提供基本类型和String类型的数据。

                                      ref:引用,用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象。

                                    • 优势:

                                      ​ 假设我们需要创建一个对象时,需要明确初始化一些数据,那么这种方式显然是很好的。因为通过构造函数创建对象时候,如果不指定具体的参数是无法把对象创建成功的。可以起到一个约束的作用。

                                    • 劣势:

                                      ​ 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

                                      三、set方法注入

                                      3.1、定义Bean

                                      public class User { private String name;
                                          private Date born;
                                          public void setName(String name) { this.name = name;
                                          }
                                          public void setBorn(Date born) { this.born = born;
                                          }
                                      }
                                      

                                      说明:set注入方式不必生成get方法

                                      3.2、主配置文件配置Bean

                                         

                                      3.3、测试

                                      @Test
                                      public void testUser() throws Exception{ // 1、读取主配置文件信息,获取核心容器对象
                                              ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
                                              User user = (User) ac.getBean("user");
                                              System.out.println(user);	// User{name='宋炜烨', born=Thu Nov 14 22:29:11 CST 2019}
                                      }
                                      

                                      3.4、总结

                                      • 涉及的标签

                                        ​ property

                                      • 出现的位置

                                        ​ bean标签的内部

                                      • 标签的属性

                                        ​ name:用于指定注入时所调用的set方法名称。

                                        ​ value:用于提供基本类型和String类型的数据。

                                        ​ ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象。

                                      • 优势

                                        ​ 创建对象时没有明确的限制,可以直接使用默认构造函数。

                                      • 劣势

                                        ​ 如果有某个成员属性必须有值,则有可能再使用该对象的时候并没有通过set方法注入值,可能拿到为空的值。

                                        四、复杂类型的注入

                                        4.1、注入数组类型【array】

                                        4.1.1、定义Bean

                                        public class Cat { private String[] arrs;
                                            public void setArrs(String[] arrs) { this.arrs = arrs;
                                            }
                                        }
                                        

                                        4.1.2、主配置文件配置Bean

                                            崔灿 时贝妮   

                                        4.2、注入List类型【list】

                                        4.2.1、定义Bean

                                        public class Cat { private List arrList;
                                            public void setArrList(List arrList) { this.arrList = arrList;
                                            }
                                        }
                                        

                                        4.2.2、主配置文件配置Bean

                                            乔峰 马夫人   

                                        4.3、注入Set类型【set】

                                        4.3.1、定义Bean

                                        public class Cat { private Set arrSet;
                                            public void setArrSet(Set arrSet) { this.arrSet = arrSet;
                                            }
                                        }
                                        

                                        4.3.2、主配置文件配置Bean

                                            段誉 鸠摩智   

                                        4.4、注入Map类型【Map】

                                        4.4.1、定义Bean

                                        public class Cat { private Map arrMap;
                                            public void setArrMap(Map arrMap) { this.arrMap = arrMap;
                                            }
                                        }
                                        

                                        4.4.2、主配置文件配置Bean

                                              

                                        4.5、注入Properties类型

                                        4.5.1、定义Bean

                                        public class Cat { private Properties props;
                                            public void setProps(Properties props) { this.props = props;
                                            }
                                        }
                                        

                                        4.5.2、主配置文件配置Bean

                                           虚竹 扫地僧  

                                        4.6、总结

                                        • 用于给List结构集合注入的标签:

                                          ​ list、array、set

                                        • 用于个Map结构集合注入的标签:

                                          ​ map 、props

                                        • 总结

                                          结构相同,标签可以互换

                                          好书推荐

                                          《Spring Batch权威指南》主要内容:

                                          • 探索Spring Batch 4中的新特性。

                                          • 使用Spring Batch项目在云环境中完成有限的批处理任务。

                                          • 通过一些示例,理解z新的基于Java和Spring Boot的配置技术

                                          • 掌握复杂场景和云环境中的批处理

                                          • 开发能够运行在现代平台上的批处理应用

                                          • 除了Spring Batch,使用Spring Portfolio的其他部分开发关键任务型批处理应用

                                            购书链接:点此进入

                                            送书活动

                                            参与方式:点击进入参与 公平公正公开 人少好中奖!