Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转
原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098
我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用其他的类中的方法,来完成我们期望的任务,大部分的情况下往往会采用在当前需要的这个类里面new一个实例出来,然后调用他的方法,那么这样的话会有个问题,就是有一天我想改变下这个类,改为其他的名称,那么这时候必须要做的是同时去调用方的类文件中改变这个改变的类的名称。这样的情况是因为代码的耦合带来了后期维护成本的增加,那么spring的出现就可以很好的起到解耦的作用,而他的核心机制就是依赖注入。
依赖注入与控制反转
依赖注入:对于spring而言,将自己置身于spring的立场上去看,当调用方需要某一个类的时候我就为你提供这个类的实例,就是说spring负责将被依赖的这个对象赋值给调用方,那么就相当于我为调用方注入了这样的一个实例。从这方面来看是依赖注入。
控制反转:对于调用方来说,通常情况下是我主动的去创建的,也就是对于这个对象而言我是控制方,我有他产生与否的权力,但是,现在变了,现在变为spring来创建对象的实例,而我被动的接受,从这一点上看,是控制反转。
这两者的意思是一致的,就看你从谁的角度去看这个问题。不同的角度那么看到的问题可能是不一样的。
依赖注入两种方式
1.设值注入
设值注入:通过set的方式注入值.Ioc容器通过成员变量的setter方法来注入被依赖的对象,这种注入方式简单,直观,因而在spring中大量的使用。
下面我们采用实际的例子来体会一下:
假设这样的一个场景,我想打印消息,这样一件事情
首先定义一个MessageService的接口。
- package com.siti.spring20160227;
- public interface MessageService {
- /**
- * 消息打印
- */
- public void printMessage();
- }
然后实现这个接口,并实现这个方法。
- package com.siti.spring20160227;
- public class MessagePrinter implements MessageService {
- @Override
- public void printMessage() {
- System.out.println("输出消息!");
- }
- }
那么对于我而言,我也定义一个person的接口
- package com.siti.spring20160227;
- public interface Person {
- /**
- * 人发送消息
- */
- public void sendMessage();
- }
我来实现人这个接口
- package com.siti.spring20160227;
- public class WangYang implements Person{
- private MessageService service;
- public void setService(MessageService service) {
- this.service = service;
- }
- @Override
- public void sendMessage() {
- this.service.printMessage();
- }
- }
Spring的配置文件:
- <?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 definitions here -->
- <bean id = "messageService" class = "com.siti.spring20160227.MessagePrinter"></bean>
- <bean id = "wy" class = "com.siti.spring20160227.WangYang">
- <property name="service" ref="messageService"></property>
- </bean>
- </beans>
测试类如下:
- package com.siti.spring20160227;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class MainTest {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- Person person = context.getBean("wy", Person.class);
- person.sendMessage();
- }
- }
2.构造注入
通过构造函数的方式注入。spring以反射的方式执行带指定参数的构造器,当执行带参数的构造器时就可以通过构造器的参数赋值给成员变量,完成构造注入。
那么现在需求变了,我需要改一些东西,下面可以注意下我主要改动了哪里:
在WangYang这个类中添加有参数和无参数的构造函数:
- package com.siti.spring20160227;
- public class WangYang implements Person{
- private MessageService service;
- <span style="color:#33ff33;">public WangYang() {
- super();
- }
- public WangYang(MessageService service) {
- this.service = service;
- }
- </span>public void setService(MessageService service) {
- this.service = service;
- }
- @Override
- public void sendMessage() {
- this.service.printMessage();
- }
- }
在Spring配置文件中,稍微改动,即将原来的设值注入换为构造注入即可。
- <?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 definitions here -->
- <bean id = "messageService" class = "com.siti.spring20160227.MessagePrinter"></bean>
- <bean id = "wy" class = "com.siti.spring20160227.WangYang">
- <!-- <property name="service" ref="messageService"></property> -->
- <span style="color:#33ff33;"><constructor-arg ref="messageService"></constructor-arg></span>
- </bean>
- </beans>
这样再次运行MainTest类,程序正常运行。所以从这里也可以体会到,spring这种解耦的方便性和重要性。
设值注入和构造注入的对比
这两种方式,效果是一样的,注入的时机不同,设值注入是先调用无参的构造函数,创建出实例后然后调用set方法注入属性值。而构造输入是通过在调用构造函数初始化实例的同时完成了注入。
设值注入的优点
1. 通过set的方式设定依赖关系显得更加直观,自然,和javabean写法类似。
2. 复杂的依赖关系,采用构造注入会造成构造器过于臃肿,spring 实例化的时候同时实例化其依赖的全部实例,导致性能下降,set方式可以避免这些问题。
3. 在成员变量可选的情况下,构造注入不够灵活。
构造注入的优点
某些特定的情况下,构造注入比设值注入好一些。
1. 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入,构造注入可以清楚的分清注入的顺序。
2. 组件的调用者无需知道组件内部的依赖关系,符合高内聚原则。
Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转的更多相关文章
- Helloworld之Spring依赖注入/控制反转(DI/IoC)版
Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...
- Spring的核心机制依赖注入
原文地址:http://developer.51cto.com/art/200610/33311.htm 本文主要讲解依赖注入(设值注入.构造注入),作用是可以使Spring将各层的对象以松耦合的方式 ...
- spring-第一篇之spring核心机制依赖注入(DI)/控制翻转(IoC)
1.spring的核心机制:依赖注入(DI)/控制翻转(IoC) 什么是依赖:A对象需要调用B对象,所以A依赖于B. 什么是注入:A对象注入一个属性B对象. 什么是依赖注入(DI):A对象依赖于B对象 ...
- Spring的核心机制——依赖注入(Dependency Inject)
Spring不仅提供对象,还提供对象的属性值,而不是由使用该对象的程序所提供的. Java应用是由一些相互协作的对象所组成的,在Spring中这种相互协作的关系就叫依赖关系. 如果A组件调用了B组件的 ...
- Spring的核心机制——依赖注入(Dependency Inject)
Spring不仅提供对象,还提供对象的属性值,而不是由使用该对象的程序所提供的. Java应用是由一些相互协作的对象所组成的,在Spring中这种相互协作的关系就叫依赖关系. 如果A组件调用了B组件的 ...
- Spring 依赖注入控制反转实现,及编码解析(自制容器)
定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...
- Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转
小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...
- 【SSH进阶之路】Spring的AOP逐层深入——采用注解完成AOP(七)
上篇博文[SSH进阶之路]Spring的AOP逐层深入——AOP的基本原理(六),我们介绍了AOP的基本原理,以及5种通知的类型, AOP的两种配置方式:XML配置和Aspectj注解方式. 这篇我们 ...
- 【SSH进阶之路】Spring的IOC逐层深入——为什么要使用IOC[实例讲解](二)
上篇博客[SSH进阶之路]Spring简介,搭建Spring环境——轻量级容器框架(一),我们简单的介绍了Spring的基本概念,并且搭建了两个版本的Spring开发环境,但是我们剩下了Spring最 ...
随机推荐
- 《C标准库》——之<ctype.h>
在没读<ctype.h>的源码之前,我一直以为我们平时用的isalnum.isdigit.isalpha等这些函数,是靠判断写出来的. 比如: int isdigit(int c){ re ...
- POJ 3233 Matrix Power Series 矩阵快速幂
设S[k] = A + A^2 +````+A^k. 设矩阵T = A[1] 0 E E 这里的E为n*n单位方阵,0为n*n方阵 令A[k] = A ^ k 矩阵B[k] = A[k+1] S[k] ...
- MATLAB格式化输出控制
format 默认格式 format short 5字长定点数 format long 15字长定点数 format short e 5字长浮点数 format long e 15字长浮点数 form ...
- JavaWeb学习记录(十九)——jstl自定义标签库之传统标签
一.传统标签 (1)JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法. public void setPageContext(PageCo ...
- 越狱Season 1-Episode 2: Allen
Season 1, Episode 2: Allen [Previously, on Prison Break] previously: 以前(预先) 前情回顾 -Judge: I find it i ...
- AI编辑SVG格式的相关问题
制作SVG:1.需要给每个图层命名,生成的SVG文件的(表示一个路径,另外还有标签等)标签就会有个id属性是这个图层的名字2.保存的时候内嵌文字可以保存为SVG或转为path格式,如果没有文字,则无所 ...
- Android调用系统分享功能以及createChooser的使用
工程结构 //效果图 点击测试分享 ...
- 在jQuery EasyUI中实现对DataGrid进行编辑
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- HTTP缓存ETAG和Last-Modified
1) 什么是"Last-Modified"? 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文 ...
- mvc:view-controller
This tag is a shorcut for defining a ParameterizableViewController that immediately forwards to a vi ...