Spring使用Setter完成依赖注入方式

编辑: admin 分类: java 发布时间: 2021-12-03 来源:互联网
目录
  • 对依赖注入的理解
  • 使用Setter完成不同类型属性的注入
    • 整体配置文件
  • Spring解决setter方式的循环依赖的原理

    对依赖注入的理解

    依赖:实体间的所有依赖由容器创建

    注入:容器负责完成实体间依赖互相注入的任务

    使用Setter完成不同类型属性的注入

    实体类Student

    package indi.stitch.pojo;
    import java.util.*;
    public class Student {
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        private Set<String> games;
        private Map<String, String> card;
        private Properties info;
        private String wife;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Address getAddress() {
            return address;
        }
        public void setAddress(Address address) {
            this.address = address;
        }
        public String[] getBooks() {
            return books;
        }
        public void setBooks(String[] books) {
            this.books = books;
        }
        public List<String> getHobbys() {
            return hobbys;
        }
        public void setHobbys(List<String> hobbys) {
            this.hobbys = hobbys;
        }
        public Set<String> getGames() {
            return games;
        }
        public void setGames(Set<String> games) {
            this.games = games;
        }
        public Map<String, String> getCard() {
            return card;
        }
        public void setCard(Map<String, String> card) {
            this.card = card;
        }
        public String getWife() {
            return wife;
        }
        public void setWife(String wife) {
            this.wife = wife;
        }
        public Properties getInfo() {
            return info;
        }
        public void setInfo(Properties info) {
            this.info = info;
        }
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' + "\n" +
                    ", address=" + address.toString() + "\n" +
                    ", books=" + Arrays.toString(books) + "\n" +
                    ", hobbys=" + hobbys + "\n" +
                    ", games=" + games + "\n" +
                    ", card=" + card + "\n" +
                    ", info=" + info + "\n" +
                    ", wife='" + wife + '\'' +
                    '}';
        }
    }
    

    实体类引用的复杂类型Address

    package indi.stitch.pojo;
    public class Address {
        private String address;
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        @Override
        public String toString() {
            return "Address{" +
                    "address='" + address + '\'' +
                    '}';
        }
    }
    

    String字符串类型注入

    <property name="name" value = "stitch" />

    复杂VO类型注入

    配置文件中增加复杂类型bean(Address)的依赖配置

    <bean id = "address" class="indi.stitch.pojo.Address">
            <property name="address" value="北京" />
        </bean>
    <bean id = "student" class = "indi.stitch.pojo.Student">

    实体类Student的bean属性依赖对其进行引用

    <property name="address" ref="address"/>

    数组类型注入

    <property name="books">
                <array>
                    <value>西游记</value>
                    <value>三国演义</value>
                    <value>红楼梦</value>
                    <value>水浒传</value>
                </array>
    </property>

    List集合类型注入

    <property name="hobbys">
                <list>
                    <value>唱歌</value>
                    <value>跳舞</value>
                    <value>打篮球</value>
                </list>
    </property>

    Set集合类型注入

     <property name="games">
                <set>
                    <value>英雄联盟</value>
                    <value>穿越火线</value>
                    <value>刺激战场</value>
                </set>
    </property>

    Map键值对类型注入

    <property name="card">
                <map>
                    <entry key="学生卡" value="123456"/>
                    <entry key="身份证" value="111111222222223333" />
                </map>
    </property>

    Properties类型注入

    <property name="info">
                <props>
                    <prop key="sex">男</prop>
                    <prop key="age">18</prop>
                </props>
    </property>

    null类型注入

    <property name="wife">
                <null />
            </property>

    整体配置文件

    <?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id = "address" class="indi.stitch.pojo.Address">
            <property name="address" value="北京" />
        </bean>
        <bean id = "student" class = "indi.stitch.pojo.Student">
            <!-- String字符串类型注入-->
            <property name="name" value = "stitch" />
            <!--复杂VO类型注入-->
            <property name="address" ref="address"/>
            <!--数组类型注入-->
            <property name="books">
                <array>
                    <value>西游记</value>
                    <value>三国演义</value>
                    <value>红楼梦</value>
                    <value>水浒传</value>
                </array>
            </property>
            <!--List集合类型注入-->
            <property name="hobbys">
                <list>
                    <value>唱歌</value>
                    <value>跳舞</value>
                    <value>打篮球</value>
                </list>
            </property>
            <!--Set集合类型注入-->
            <property name="games">
                <set>
                    <value>英雄联盟</value>
                    <value>穿越火线</value>
                    <value>刺激战场</value>
                </set>
            </property>
            <!--Map键值对类型注入-->
            <property name="card">
                <map>
                    <entry key="学生卡" value="123456"/>
                    <entry key="身份证" value="111111222222223333" />
                </map>
            </property>
            <!--Properties类型注入-->
            <property name="info">
                <props>
                    <prop key="sex">男</prop>
                    <prop key="age">18</prop>
                </props>
            </property>
            <!--null类型注入-->
            <property name="wife">
                <null />
            </property>
        </bean>
    </beans>
    

    测试类

    import indi.stitch.pojo.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student  = (Student) context.getBean("student");
            System.out.println(student.toString());
        }
    }
    

    输出结果:

    在这里插入图片描述

    Spring解决setter方式的循环依赖的原理

    1.通过构造函数创建A对象 (A对象是半成品,还没有注入属性和调用init方法)

    2.将半成品A对象封装成工厂对象存入三级缓存

    3.A对象需要注入B对象,发现缓存里还没有B对象,开始创建B对象

    4.通过构造函数创建B对象(B对象是半成品,还没有注入属性和调用init方法)同样在三级缓存中创建B工厂对象

    5.B对象需要注入A对象;从三级缓存中获取A工厂对象,使用工厂对象获取半成品A对象同时放入

    二级缓存中,提前曝光A对象,同时删除A工厂对象

    6.B对象继续注入其它属性和初始化,之后将完成品B对象放入完成品缓存一级缓存,同时删除B工厂对象

    7.A对象获取单例B的引用完成属性注入

    8.B对象继续注入其它属性和初始化,之后将完成品A对象放入完成品缓存一级缓存同时删除二级缓存中的A

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。

    【转自:http://www.nextecloud.cn/jap.html 欢迎转载】