一、什么是依赖注入

DI (Dependency Injection):依赖注入是指在 Spring IOC 容器创建对象的过程中,将所依赖的对象通过配置进行注入。我们可以通过依赖注入的方式来降低对象间的耦合度。

在软件工程中,对象之间的耦合度就是对象之间的依赖性。对象之间的耦合越高,维护成本越高,因此对象的设计应使对象之间的耦合越小越好。

1 类的关系

继承、实现、依赖、关联、聚合、组合。

2 关系强度

继承 = 实现 > 组合 > 聚合 > 关联 > 依赖

二、为什么使用依赖注入

1 开闭原则

1.1 定义

OCP (Open Close Principle): 软件本身应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。

1.2 开闭原则优点

易扩展。开闭原则的定义就要求对扩展开放。

易维护。软件开发中,对现有代码的修改是一件很有风险的事情,符合开闭原则的设计在扩展时无需修改现有代码,规避了这个风险,大大提交了可维护性。

2 高内聚,低耦合

高内聚是指相关度比较高的部分尽可能的集中,不要分散。

低耦合就是说两个相关的模块尽可以能把依赖的部分降低到最小,不要产生强依赖。

三、依赖注入的方式

在使用依赖注入时,如果注入的是 Bean 对象,那么要求注入的 Bean 对象与被注入的Bean 对象都需要 Spring IOC 容器来实例化。

1 通过 Set 方法注入

需要为注入的成员变量提供 Set 方法。

1.1 POJO中添加属性、set方法和toString方法

public class GirlfriendOYY implements Girlfriend {private double hight;private String education;@Overridepublic String toString() {return "GirlfriendOYY{" +"hight=" + hight +", education='" + education + '\'' +'}';}public double getHight() {return hight;}public void setHight(double hight) {this.hight = hight;}public String getEducation() {return education;}public void setEducation(String education) {this.education = education;}
}

1.2 Spring的xml配置文件

    <!--1.1 通过构造方法创建对象--><bean id="gf1" class="com.dyh.pojo.impl.GirlfriendOYY"scope="prototype" lazy-init="false"><property name="education" value="本科" /><property name="hight" ><value>1.65</value></property></bean>

1.3 测试

public class TestGirlfriend {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");Girlfriend gf = (Girlfriend) ac.getBean("gf1");System.out.println(gf);}
}

运行结果

2 通过构造方法注入

Bean 对象中需要提供有参的构造方法

name:根据参数名称识别参数

index:根据参数的位置来识别参数

type:根据参数的类型识别参数

2.1 POJO中添加有参构造方法

public class GirlfriendOYY implements Girlfriend {private double hight;private String education;public GirlfriendOYY(double hight, String education) {this.hight = hight;this.education = education;}
}

2.2 Spring的xml配置文件

 <bean id="gf4" class="com.dyh.pojo.impl.GirlfriendOYY"><constructor-arg name="education" value="专科"/><constructor-arg name="hight" ><value>1.65</value></constructor-arg></bean><bean id="gf5" class="com.dyh.pojo.impl.GirlfriendOYY"><constructor-arg index="0" value="1.68" /><constructor-arg index="1" ><value>高中</value></constructor-arg></bean><bean id="gf6" class="com.dyh.pojo.impl.GirlfriendOYY"><constructor-arg type="double" value="1.73" /><constructor-arg type="java.lang.String" ><value>硕士</value></constructor-arg></bean>

2.3 测试

public class TestGirlfriend {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");Girlfriend gf = (Girlfriend) ac.getBean("gf4");System.out.println(gf);gf = (Girlfriend) ac.getBean("gf5");System.out.println(gf);gf = (Girlfriend) ac.getBean("gf6");System.out.println(gf);}
}

运行结果:

3 自动注入

自动注入的方式有两种,一种是全局配置自动注入,另一种是局部配置自动注入。

无论全局配置或局部单独配置,都有 5 个值可以选择:

no:当 autowire 设置为 no 的时候,Spring 就不会进行自动注入。

byName:在 Spring 容器中查找 id 与属性名相同的 bean,并进行注入。需要提供 set 方法。

byType:在 Spring 容器中查找类型与属性名的类型相同的 bean,并进行注入。需要提供 set 方法。

constructor:仍旧是使用 byName 方式,只不过注入的时候,使用构造方式进行注入。

default:全局配置的 default 相当于 no,局部的 default 表示使用全局配置设置。

3.1 局部自动注入

通过 bean 标签中的 autowire 属性配置自动注入。

有效范围:仅针对当前 bean 标签生效。

3.1.1 POJO

接口:

public interface GirlfriendProxyService {Girlfriend findGirlFriend();
}

实现类:

public class GirlfriendProxyServiceImpl implements GirlfriendProxyService {Girlfriend girlfriend;public GirlfriendProxyServiceImpl(){}public GirlfriendProxyServiceImpl(Girlfriend girlfriend) {this.girlfriend = girlfriend;}public Girlfriend getGirlfriend() {return girlfriend;}public void setGirlfriend(Girlfriend girlfriend) {this.girlfriend = girlfriend;}@Overridepublic Girlfriend findGirlFriend() {return this.girlfriend;}
}

3.1.2 Spring的xml配置

 <bean id="gf6" class="com.dyh.pojo.impl.GirlfriendOYY" name="girlfriend"><constructor-arg type="double" value="1.73" /><constructor-arg type="java.lang.String" ><value>硕士</value></constructor-arg></bean><!--autowire表示自动装配 :byName 根据bean的名字去自动转配(name属性值需要跟构造方法中的name属性值一致),byType根据类型自动装配--><bean id="gfService"class="com.dyh.service.impl.GirlfriendProxyServiceImpl" autowire="byName"><!--<property name="girlfriend" ><ref bean="gf6"/></property>--></bean>

3.1.3 测试

public class TestGFServiceByName {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");GirlfriendProxyServiceImpl gfService = (GirlfriendProxyServiceImpl) ac.getBean("gfService");Girlfriend girlfriend = gfService.getGirlfriend();System.out.println(girlfriend);}
}

运行结果:

如果将上述Spring的xml配置中的autowire属性值改成byType,表示根据类型自动装配,则会报如下错误!

3.2 全局自动注入

通过 beans 标签中的default-autowire  属性配置自动注入。

有效范围:配置文件中的所有 bean 标签都生效。

四、依赖注入的数据类型

1 注入 Bean 对象

 <bean id="gfService"class="com.dyh.service.impl.GirlfriendProxyServiceImpl" autowire="byType"><property name="girlfriend" ><ref bean="gf6"/></property></bean>

2 注入基本数据类型和字符串

<bean id="gf1" class="com.dyh.pojo.impl.GirlfriendOYY"scope="prototype" lazy-init="false"><property name="education" value="本科" /><property name="hight" ><value>1.65</value></property></bean>

3 注入 List

3.1 POJO

public class GirlfriendOYY implements Girlfriend {private double hight;private String education;private List<String> hobby;        // 兴趣爱好public List<String> getHobby() {return hobby;}public void setHobby(List<String> hobby) {this.hobby = hobby;}    @Overridepublic String toString() {return "GirlfriendOYY{" +"hight=" + hight +", education='" + education + '\'' +", hobby=" + hobby +'}';}
}

3.2 Spring的xml配置

   <bean id="gf1" class="com.dyh.pojo.impl.GirlfriendOYY"scope="prototype" lazy-init="false"><property name="education" value="本科" /><property name="hight" ><value>1.65</value></property><property name="hobby"><list><value>看电影</value><value>旅游</value></list></property></bean>

3.3 测试

public class TestGirlfriend {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");Girlfriend gf = (Girlfriend) ac.getBean("gf1");System.out.println(gf);}
}

运行结果:

4 注入 Set

同上。

5 注入 Map

5.1 POJO修改

public class GirlfriendOYY implements Girlfriend {private double hight;private String education;private List<String> hobby;private Map<String, String> parents;    // 父母情况public Map<String, String> getParents() {return parents;}public void setParents(Map<String, String> parents) {this.parents = parents;}@Overridepublic String toString() {return "GirlfriendOYY{" +"hight=" + hight +", education='" + education + '\'' +", hobby=" + hobby +", parents=" + parents +'}';}
}

5.2 Spring的xml配置修改

 <bean id="gf1" class="com.dyh.pojo.impl.GirlfriendOYY"scope="prototype" lazy-init="false"><property name="education" value="本科" /><property name="hight" ><value>1.65</value></property><property name="hobby"><list><value>看电影</value><value>旅游</value></list></property><property name="parents" ><map><entry key="father" value="zs" /><entry key="mother" value="ls" /></map></property></bean>

测试类不用修改,运行结果:

6 注入Properties

略。

Spring依赖注入相关推荐

  1. arg是什么函数_java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪...

    前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...

  2. Java程序员进阶——Spring依赖注入原理分析

    Spring依赖注入原理分析 下面谈谈Spring是如何实现反转模式IOC或依赖注入模式DI: 平时,我们需要生成一个对象,使用new语法,如一个类为A public class A{public v ...

  3. spring 依赖注入

    Technorati 标记: spring,依赖注入,DI,ioc 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的 ...

  4. java接口注入对象的意义_Java Web系列:Spring依赖注入基础

    一.Spring简介 1.Spring简化Java开发 Spring Framework是一个应用框架,框架一般是半成品,我们在框架的基础上可以不用每个项目自己实现架构.基础设施和常用功能性组件,而是 ...

  5. spring依赖注入原理(转载)

    关于spring依赖注入原理的文章在网络上已经有很多,我要写的这篇文章原文出自http://taeky.iteye.com/blog/563450,只所以再一次写下来只是为了一为自己收藏,方便以后的复 ...

  6. Spring依赖注入:注解注入总结

    更多11 spring 依赖注入 注解 java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.C ...

  7. spring依赖注入_Spring源码阅读:Spring依赖注入容器

    依赖注入 依赖注入是Spring框架最核心的能力,Spring框架提供的AOP,WebMVC等其它功能都是以依赖注入容器作为基础构建的,Spring依赖注入容器类似于一个用于组装对象的框架内核,任何应 ...

  8. diy实现spring依赖注入

    [README] 本文diy代码实现了 spring 依赖注入,一定程度上揭示了依赖注入原理: [1]控制反转-Inversion of Control 是一种编码思想,简而言之就是 应用程序A可以使 ...

  9. spring依赖注入_Spring依赖注入

    spring依赖注入 介绍: 在设计良好的Java应用程序中,这些类应尽可能独立. 这样的设计提高了组件的可重用性. 它还使对各个组件进行单元测试变得更加容易. 依赖注入的概念促进了Java对象之间的 ...

  10. spring依赖注入_Spring的依赖注入陷阱

    spring依赖注入 Spring框架中有三种注入变量: 基于二传手的注射 基于构造函数的注入 基于现场的注入 这些机制中的每一种都有优点和缺点,并且不仅只有一种正确的方法. 例如现场注入: @Aut ...

最新文章

  1. MIT黑科技:“不开卷也有益”,计算机不翻书就能读完一本书
  2. TCP/IP之传输层(一)
  3. 数据结构和算法分析: 第五章 散列
  4. Python命名空间的本质
  5. git 创建webpack项目_一次create-react-app创建项目升级webpack的流水账
  6. C++:类访问修饰符
  7. hadoop系列一:hadoop集群安装
  8. 莫烦强化学习-Q Learning
  9. 101名女职工血清总胆固醇测量结果spss描述统计分析
  10. 高校大数据教学实训平台以及实验室建设解决方案-美林数据
  11. 从前端页面上下载为png格式的图片
  12. 菜鸟日记(yzy):opencMS系统-XML内容管理文件开发
  13. springboot 成员变量_SpringBoot就是这么简单
  14. NJCTF writeup
  15. linux的veth导致网络不通,使用veth-pair和bridge搭建的本地网络环境网络不通
  16. 计算机专业排名211大学排名,计算机专业大学排名,计算机专业强的211!
  17. html5 图片处理 开源,AlloyImage 基于 HTML5 的专业级图像处理开源引擎 - 文章教程...
  18. [c]设计程序,输入一个圆柱体的半径r和高h,求圆柱体的底周长c、底面积s、侧面积s1、表面积s2和体积v。
  19. 机械cad 讲c语言编程,机械CAD讲解.doc
  20. 计算机组成原理第一章课件,计算机组成原理第一章课件.ppt

热门文章

  1. Wireshark过滤器写法总结
  2. 【你离诺贝尔奖也就20米】记一次诺奖得主讲座聆听感受
  3. html5仿ios底部菜单栏,仿苹果电脑任务栏菜单
  4. 计算机设计大赛一人能报几个,我校在中国大学生计算机设计大赛获多个奖项
  5. 自考汉语言文学本科要考几门?专业有哪些课程?
  6. Java for循环和foreach循环区别
  7. 福州铁通DNS是多少
  8. Direct2D 介绍
  9. 前端获取北京时间_js获取北京时间
  10. 云南人,你的家乡在哪里?