简单解析依赖注入(控制反转)在Spring中的应用

时间:2022-09-08 18:21:35

IoC——Inversion of Control  控制反转
DI——Dependency Injection   依赖注入

大家都知道,依赖注入是Spring中非常重要的一种设计模式。可能很多初学者对这种看起来高深的东西有一种抗拒,这里就
 简单介绍一下到底什么是依赖注入,Spring到底又到底是如何运用依赖注入的。

依赖关系:在A组件中要引用B组件的对象,则称A依赖于B
依赖关系会造成各组件之间的硬编码,为解决依赖关系,一般的解决方法如下:

1、A组件先创建B组件,在调用B组件方法
2、A组件先通过B组建的工厂获取B组件,再调用B组件方法
3、A、B两个组件都由容器管理,容器先将B组件传给A组件,A组件直接调用B的方法

第一个是传统的方法,并没有解决依赖关系
第二个则造成了A与工厂类的耦合
Spring就是通过第三种方法解决的,被称为依赖注入。

依赖注入和控制反转其实就是将的同一个设计模式,只是从不同的角度进行描述的。
依赖注入是从组件之依赖关系讲的,指A不再主动的去创建B组件,而变为被动的接受容器的注入的B对象;
而控制反转是从对对象的控制方面讲的,是指程序代码直接操控的对象的调用权交给容器。

依赖注入包括两种方式,一是设值注入,一是构造注入。下面就以Spring中具体代码实现例子来解释两种依赖注入方式:

1、数据库操作的接口:
  public interface UserDao { void save(String name,String pass); }

2、接口两种实现方式:
程序只是简单模拟连接数据库,并没有真正进行连接:
(1)

 import com.csu.test.dao.UserDao;

 public class UserDaoJdbc implements UserDao{

     @Override
public void save(String name, String pass) { System.out.println("模拟通过JDBC存储用户:"+name );
} }

(2)

 import com.csu.test.dao.UserDao;

 public class UserDaoHibernate implements UserDao{

     @Override
public void save(String name, String pass) { System.out.println("模拟通过Hibernate存储用户:"+name );
} }

3、Service 层:

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.csu.test.dao.UserDao; public class UserService { private UserDao userDao; //1、通过为userDao提供sett方法,在配置文件中的property属性进行配置,即可解决A依赖B的问题
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} //2、通过构造方法进行配置
public UserService(UserDao userDao){
this.userDao = userDao;
} public void addUser(String name,String pass){
//UserDao userDao = new UserDao();
//UserDao userDao = new UserDaoJdbc();
//UserDao userDao = UserDaoFactory.getUserDao(); /**
//spring中可以向创建Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao = ctx.getBean("userdao",UserDao.class);
userDao.save(name, pass);
**/ userDao.save(name, pass);
}
}

4、配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<!-- 整个Spring 文件的根元素就是beans -->
<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="userdaoJdbc" class="com.csu.test.dao.impl.UserDaoJdbc"/>
<bean id="userdaoHibernate" class="com.csu.test.dao.impl.UserHibernate"/> <bean id = "userService" class="com.csu.test.service.UserService">
<!-- property就是控制调用setter方法 -->
<!-- <property name = "userDao" ref = "userdaoJdbc"/> --> <!-- 调用有参构造器 -->
<constructor-arg ref = "userdaoJdbc"/> <!--更换实现方式-->
<!--
<property name = "userDao" ref = "userdaoHibernate"/>
<constructor-arg ref = "userdaoHibernate"/>
-->
</bean> </beans>

这里重点解释一下吧:
在service层中的UserService类中,是依赖于数据库操作对象UserDao的,如大家所见,UserService类中我们并没有直接new出UserDao对象的,
怎么做到的呢:两种方式
(1)、设值注入:
对应函数为:public void setUserDao(UserDao userDao)
在配置文件中,对应id为userService的Bean设置,有一个property的属性,这意味着,当我们在得到userService的Bean对象时,根据property的属性,容器会自动调用
与name相应的set函数,即上面的函数,传入的参数依旧为Bean对象,所以用ref

(2)、构造注入
对应函数为:public UserService(UserDao userDao)
与设值注入类似,<constructor-arg>标签的含义就是调用构造函数,传递参数,自动实例化UserDao。

当然两种方式不要重复设置,上面已经注释掉一种,可以自己再测试一下。

5、测试主类:

 import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.csu.test.dao.UserDao;
import com.csu.test.service.UserService; public class TestService { UserService u; @Test
public void testAddUser(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
u = ctx.getBean("userService",UserService.class); u.addUser("admin", "123");
}
}

这样,我们就实现了面向接口编程,具体的实现类配置在配置文件即可,像上面的代码,我们只需要更改配置文件,
就可以改变数据库的操作对象。

简单解析依赖注入(控制反转)在Spring中的应用

简单解析依赖注入(控制反转)在Spring中的应用的更多相关文章

  1. Helloworld之Spring依赖注入&sol;控制反转&lpar;DI&sol;IoC&rpar;版

    Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...

  2. C&num;依赖注入控制反转IOC实现详解

    原文:C#依赖注入控制反转IOC实现详解 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. ...

  3. PHP关于依赖注入&lpar;控制反转&rpar;的解释和例子说明

    PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-20 10:12)   阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即 1111 ...

  4. Spring 依赖注入控制反转实现,及编码解析(自制容器)

    定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...

  5. Spring进阶之路&lpar;1&rpar;-Spring核心机制:依赖注入&sol;控制反转

    原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...

  6. Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转

    小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...

  7. laravel5&period;2总结--服务容器&lpar;依赖注入&comma;控制反转&rpar;

    1.依赖 我们定义两个类:class Supperman 和 class Power,现在我们要使用Supperman ,而Supperman 依赖了Power class Supperman { p ...

  8. 依赖注入&amp&semi;控制反转

    IoC——Inversion of Control  控制反转DI——Dependency Injection   依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依 ...

  9. IoC 依赖注入、以及在Spring中的实现

    资源来自网络: 去年火得不行的Spring框架,一般的书籍都会从IoC和AOP开始介绍起,这个IoC概念,个人感觉资料里都写得让人看得有些痛苦,所谓IoC,就是控制反转(Inversion of Co ...

随机推荐

  1. Drupal网站开发实践系列

    这一系列文章会记录我最近一个项目的开发历程.包括用到的模块,功能的具体实现,调用的API,还有主题的制作,一部分前端信息等. 该网站基于Drupal7+Commerce制作,主题部分基本完全自定义,没 ...

  2. python&lowbar;way day13 sqlalchemy

    sqlalchemy 一对多 多对多 1.一对多 一.#创建表结构 class Host(Base): #所有的子类都继承这个基类 #创建表结构 __tablename__ = 'hosts' id ...

  3. 机房收费系统之uml图——初版

    说起uml图,在我心中最难的当属类图无疑.虽然敲了三层的小例子,但真正让把三层和uml图结合起来,并且还要考虑设计模式的时候,总是让人有一种无从下手的感觉,不过还好,通过这半个多月的思考与探索(竟然用 ...

  4. 粒子系统1:简介&amp&semi;工具使用

    直接使用工具来感受一下粒子系统的强大威力吧. 网络上有很多粒子编辑器,大多数都是收费的.magicalsoft提供了一个免费的粒子编辑器(该工具目前只有mac版本),界面如下: 我们将针对这个编辑器来 ...

  5. poj 2987 最大闭合子图

    思路: 这题考的是最大闭权图.只要知道怎么求最大闭权图就知道怎么做.但好像有点卡模版,要高效的模版才行. #include <iostream> #include <stdio.h& ...

  6. Activity之间通过intent 传递Map

    //传递 Map<String,Object> data=orderlist.get(arg2-1); SerializableMap tmpmap=new SerializableMap ...

  7. hdu4035(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4035 题意:有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结 ...

  8. java中由类名和方法名字符串实现其调用【反射机制】

    js里通过eval()函数,在知道某个方法名是可以实现调用该方法,那么在java里边又怎么实现的呢? java里边是通过反射机制来实现,代码如下: import java.lang.reflect.M ...

  9. axure原型设计

    在上一个学期的学习中,我们已经初步学习了axure的使用方法,它可以为负责定义需求设计,功能和界面的人员能快速设计出所需产品. 引入:在我们想为软件设计原型的时候,纸质原型很难表达交互的界面,与此同时 ...

  10. 用js实现一个简单的mvvm

    这里利用的object.defineproperty() 方法; <input     id='input'><p id='p'><p/>js: const dat ...