zoukankan      html  css  js  c++  java
  • 浅谈spring依赖注入

    了解依赖注入

    前言

    先了解下控制反转--转自知乎的国哥

    如果一个类A 的功能实现需要借助于类B,那么就称类B是类A的依赖,如果在类A的内部去实例化类B,那么两者之间会出现较高的耦合,一旦类B出现了问题,类A也需要进行改造,如果这样的情况较多,每个类之间都有很多依赖,那么就会出现牵一发而动全身的情况,程序会极难维护,并且很容易出现问题。要解决这个问题,就要把A类对B类的控制权抽离出来,交给一个第三方去做,把控制权反转给第三方,就称作控制反转(IOC Inversion Of Control)控制反转是一种思想,是能够解决问题的一种可能的结果,而依赖注入(Dependency Injection)就是其最典型的实现方法。由第三方(我们称作IOC容器)来控制依赖,把他通过构造函数、属性或者工厂模式等方法,注入到类A内,这样就极大程度的对类A和类B进行了解耦

    想理解控制反转,就得想清楚这个第三方,在spring中便是IOC容器。将原本两个耦合性很强的对象分给中介第三方进行控制。

    依赖注入是实现控制反转的一种方式,依赖注入是将实例变量传入到一个对象中去的过程、方式、一种设计模式。依赖注入方式下,注入将依赖传给调用方,不是像原来的调用方直接使用依赖。所以很明显也是为了解耦,参考下wiki的图,了解大概分类

    image-20200526220650913

    可以参考下官网的介绍

    image-20200526211204989

    上面的官网中讲到依赖注入是依靠这两个主要的方式依赖-基于构造器的依赖注入和基于setter的依赖注入。下面就讲下详细的实现方式。

    实现依赖注入

    1、构造器注入

    在上一篇的spring入门篇提了,特别是三种方式,这里再记录一下

    环境

    先总体的项目小测配置以及定义的各个类

    image-20200526152135081

    实体类

    package com.yhy.pojo;
    
    public class Hello {
        private String str;
    
        public Hello(String str) {
            this.str = str;
        }
    
        /**
         * @return String return the str
         */
        public String getStr() {
            return str;
        }
    
        /**
         * @param str the str to set
         */
        public void setStr(String str) {
            this.str = str;
        }
    
        public void show() {
            System.out.println(str);
        }
    
    }
    

    测试类

     @Test
        public void test()
        {
            //获得spring的上下文内容
            //拿到容器
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            //使用容器获得对象
            Hello hello = (Hello) context.getBean("hello");
           
            hello.show();
        }
    

    使用有参构造有几个方法

    beans.xml中使用三种方式

    • 使用参数名
     <bean id="hello" class="com.yhy.pojo.Hello">
            <constructor-arg  name="str" value="yhy"/>
        </bean>
    
    • 使用下标索引
      <bean id="hello" class="com.yhy.pojo.Hello">
            <!-- 从零开始的索引值,多个参数的时候再使用别的参数 -->
            <constructor-arg index="0" value="hello world"/>
        </bean>
    

    image-20200526151759464

    • 使用参数的类型来配置
      <bean id="hello" class="com.yhy.pojo.Hello">
            <constructor-arg type="java.lang.String" value="hello spring"/>
        </bean>
    

    image-20200526152947985

    其他

    在.xml配置文件中还有两个选项。

    image-20200526153337576

    2、set方法注入

    这个方式强调bean类要有set方法,在实例化后调用set方法完成注入。

    image-20200526222752373

    定义一个person类来测试下set方法注入

    注入的类型不同使用的不同参数在配置bean中。如下图,可以有多个选择在propety中,一些标签都是可以直接秒懂的。

    image-20200526225254125

    • 常量注入

    image-20200526224651374

    • bean注入
     <!-- bean注入 ref进行引入-->
            <property name="address" ref="addr"></property>
    
    • 数组注入
     <!-- 数组注入 -->
            <property name="books">
                <array>
                    <value>悲惨世界</value>
                    <value>水浒传</value>
                    <value>金瓶X</value>
                </array>
            </property>
    
    • 列表注入
        <!-- list注入 -->
            <property name="hobbies">
                <list>
                    <value>打篮球</value>
                    <value>健身</value>
                    <value>游泳</value>
                </list>
            </property>
    
    • map注入
     <!-- map注入 -->
            <property name="card">
                <map>
                    <entry key="银行卡" value="82937472389"></entry>
                    <entry key="身份证" value="2345382937472389"></entry>
                </map>
            </property>
    
    • properties注入
     <!-- properties注入 -->
            <property name="info">
                <props>
                    <prop key="id">201705239</prop>
                    <prop key="url">yhytj.top</prop>
                    <prop key="name">yhy</prop>
                </props>
            </property>
    

    最后的测试类

        public void test() {
            // 获得spring的上下文内容
            // 拿到容器
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            // 使用容器获得对象
            Person person = (Person) context.getBean("person");
    //这里定义了一个show方法,输出格式,vscode自动生成tostring还不熟。使用插件生成这个
            person.show();
        }
    

    image-20200526232536118

    • 最后输出

    image-20200526232613109

    拓展命名空间

    在官网上还可以使用p命名空间c命名空间简化工作,但其实有idea开发等工具,有时也差不多了,大家可以多多了解下,我只是用了个小测试来了解。

    image-20200527092515079

    image-20200527092439190

    image-20200527092935559

    还有一个c命名空间,对应着constructor-arg,这里就不走小demo,可以上官网了解一些

  • 相关阅读:
    PAT A1097 Deduplication on a Linked List (25 分)——链表
    PAT A1115 Counting Nodes in a BST (30 分)——二叉搜索树,层序遍历或者dfs
    PAT A1113 Integer Set Partition (25 分)——排序题
    PAT A1112 Stucked Keyboard (20 分)——字符串
    PAT A1118 Birds in Forest (25 分)——并查集
    JAVA入门之程序设计环境搭建
    Win7命令终端基础配色指南
    泛微e-cology和Oracle无法启动的解决方案
    C指针和数组
    float类型与16进制的相互转换
  • 原文地址:https://www.cnblogs.com/yhycoder/p/12970726.html
Copyright © 2011-2022 走看看