zoukankan      html  css  js  c++  java
  • Spring详解(三)------DI依赖注入


      上一篇博客我们主要讲解了IOC控制反转,也就是说IOC 让程序员不在关注怎么去创建对象,而是关注与对象创建之后的操作,把对象的创建、初始化、销毁等工作交给spring容器来做。那么创建对象的时候,有可能依赖于其他的对象,即类的属性如何赋值?这也是我们这篇博客讲解 Spring 另一个核心要点:DI依赖注入。

      PS:本篇博客源码链接:百度云盘/Java实例/java框架—spring/Spring_02_DI.zip

    1、什么是DI依赖注入?

      spring动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

      简单来说什么是依赖注入,就是给属性赋值(包括基本数据类型和引用数据类型)

    2、利用 set 方法给属性赋值

      第一步:创建工程,并导入相应的 jar 包

      第二步:创建实体类 Person

    package com.ys.di;
     
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
     
    public class Person {
        private Long pid;
        private String pname;
        private Student students;
        private List lists;
        private Set sets;
        private Map maps;
        private Properties properties;
         
        public Long getPid() {
            return pid;
        }
        public void setPid(Long pid) {
            this.pid = pid;
        }
        public String getPname() {
            return pname;
        }
        public void setPname(String pname) {
            this.pname = pname;
        }
        public Student getStudents() {
            return students;
        }
        public void setStudents(Student students) {
            this.students = students;
        }
        public List getLists() {
            return lists;
        }
        public void setLists(List lists) {
            this.lists = lists;
        }
        public Set getSets() {
            return sets;
        }
        public void setSets(Set sets) {
            this.sets = sets;
        }
        public Map getMaps() {
            return maps;
        }
        public void setMaps(Map maps) {
            this.maps = maps;
        }
        public Properties getProperties() {
            return properties;
        }
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
         
    }

    我们看到这个实体类包括引用类型 Student 类,基本数据类以及集合数据类型。

      第三步:在 applicationContext.xml 中进行赋值

    <!--
        property是用来描述一个类的属性
        基本类型的封装类、String等需要值的类型用value赋值
        引用类型用ref赋值
    -->
    <bean id="person" class="com.ys.di.Person">
        <property name="pid" value="1"></property>
        <property name="pname" value="vae"></property>
        <property name="students">
            <ref bean="student"/>
        </property>
         
        <property name="lists">
            <list>
                <value>1</value>
                <ref bean="student"/>
                <value>vae</value>
            </list>
        </property>
         
        <property name="sets">
            <set>
                <value>1</value>
                <ref bean="student"/>
                <value>vae</value>
            </set>
        </property>
         
        <property name="maps">
            <map>
                <entry key="m1" value="1"></entry>
                <entry key="m2" >
                    <ref bean="student"/>
                </entry>
            </map>
        </property>   
         
        <property name="properties">
            <props>
                <prop key="p1">p1</prop>
                <prop key="p2">p2</prop>
            </props>
        </property>  
         
    </bean>
     
     
    <bean id="student" class="com.ys.di.Student"></bean>

    第四步:测试

    //利用 set 方法给对象赋值
        @Test
        public void testSet(){
            //1、启动 spring 容器
            //2、从 spring 容器中取出数据
            //3、通过对象调用方法
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("applicationContext.xml");
            Person person = (Person) context.getBean("person");
            System.out.println(person.getPname());//vae
        }

    3、利用 构造函数 给属性赋值

      第一步:在实体类 Per'son.java 中添加两个构造方法:有参和无参

    //默认构造函数
        public Person(){}
        //带参构造函数
        public Person(Long pid,Student students){
            this.pid = pid;
            this.students = students;
        }

    第二步:在 applicationContext.xml 中进行赋值

    <!-- 根据构造函数赋值 -->
        <!--
            index  代表参数的位置  从0开始计算
            type   指的是参数的类型,在有多个构造函数时,可以用type来区分,要是能确定是那个构造函数,可以不用写type
            value  给基本类型赋值
            ref    给引用类型赋值
          -->
        <bean id="person_con" class="com.ys.di.Person">
            <constructor-arg index="0" type="java.lang.Long" value="1">
            </constructor-arg>       
            <constructor-arg index="1" type="com.ys.di.Student" ref="student_con"></constructor-arg>
        </bean>
        <bean id="student_con" class="com.ys.di.Student"></bean>

    第三步:测试

    //利用 构造函数 给对象赋值
        @Test
        public void testConstrutor(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            Person person = (Person) context.getBean("person_con");
            System.out.println(person.getPid());//1
        }

    总结: 

      1、如果spring的配置文件中的bean中没有<constructor-arg>该元素,则调用默认的构造函数

      2、如果spring的配置文件中的bean中有<constructor-arg>该元素,则该元素确定唯一的构造函数

  • 相关阅读:
    标签的讲解
    属性分类
    LeetCode 003. 无重复字符的最长子串 双指针
    Leetcode 136. 只出现一次的数字 异或性质
    Leetcode 231. 2的幂 数学
    LeetCode 21. 合并两个有序链表
    象棋博弈资源
    acwing 343. 排序 topsort floyd 传播闭包
    Leetcode 945 使数组唯一的最小增量 贪心
    Leetcode 785 判断二分图 BFS 二分染色
  • 原文地址:https://www.cnblogs.com/chedahui/p/10062203.html
Copyright © 2011-2022 走看看