了解依赖注入

前言

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

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

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

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

可以参考下官网的介绍

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

实现依赖注入

1、构造器注入

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

环境

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

实体类

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>

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

其他

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

2、set方法注入

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

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

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

  • 常量注入

  • 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();
}

  • 最后输出

拓展命名空间

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

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

最新文章

  1. c语言文件读写操作总结
  2. Html5+NodeJS——拖拽多个文件上传到服务器
  3. javascript实例备忘
  4. Spring中的IOC\DI\AOP等概念的简单学习
  5. Android中AIDL通信机制分析
  6. web中session与序列化的问题
  7. VMware 虚拟机使用 NAT 方式联网
  8. Java实现批量修改文件名称
  9. CodeForces 384A Coder
  10. 加入ScrollView后OnGestureListener无效的解决办法
  11. oracle 字段上下两条记录的相减
  12. 阿里巴巴笔试整理系列 Session2 高级篇
  13. JSP视频
  14. (一)java多线程之Thread
  15. iOS-xcode代码统计
  16. vue2 作用域插槽slot-scope详解
  17. Java获取指定包名下的所有类的全类名的解决方案
  18. 计算概论(A)/基础编程练习(数据成分)/3:整数的个数
  19. 集群RedHat6.5+JDK1.8+Hadoop2.7.3+Spark2.1.1+zookeeper3.4.6+kafka2.11+flume1.6环境搭建步骤
  20. HDU-1069.MonkeyandBanana(LIS)

热门文章

  1. TCP 可靠传输
  2. 在html中使用vue组件
  3. E - 梦幻岛宝珠 HYSBZ - 1190 变形01背包 难
  4. CC2530通用IO口的输入输出
  5. webpack-基础知识
  6. MYSQL连接端口被占引入文件路径错误
  7. Linux 内核代码风格
  8. C语言进阶_goto与void解析
  9. Hexo 博客利用 Nginx 实现中英文切换
  10. Pytorch使用分布式训练,单机多卡