zoukankan      html  css  js  c++  java
  • 【SSH进阶之路】Spring的IOC逐层深入——为什么要使用IOC[实例讲解](二)

          上篇博客【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一),我们简单的介绍了Spring的基本概念,并且搭建了两个版本的Spring开发环境,但是我们剩下了Spring最核心的两大技术:IoC和AOP,没有深入介绍。从这篇博文开始,我们开始一一的深入学习Spring的两个核心。Spring目前最引人注目的地方,就是IOC=Inversion  OControl(控制反转)或者DI=Dependence  Injection(依赖注入)的设计思想。

          这篇博客我们使用传统方式(即不使用Spring)来实现一个添加用户的实例,再同理使用Spring实现添加用户的实例,对比学习IoC的概念,以及为什么使用IoC等等,最后,简单总结。下面我们开始:

     

    传统方式:

     

    客户端:

    public class Client {
    
    	public static void main(String[] args){
    		//由我们的应用程序负责服务(对象)定位,主动发起查找
    		UserManager userManager = new UserManagerImpl();
    		userManager.addUser("jiuqiyuliang", "123456");
    	}
    }

    业务逻辑层:

    UserManager接口:添加用户的方法

    public interface UserManager {
    
    	public void addUser(String userName,String password);
    }

    UserManager实现

    public class UserManagerImpl implements UserManager{
    
    	@Override
    	public void addUser(String userName, String password) {
    		//由我们的应用程序负责服务(对象)定位,主动发起查找
    		//UserDao userDao = new UserDao4MysqlImpl();
    		UserDao userDao = new UserDao4OracleImpl();
    		userDao.addUser(userName, password);
    	}
    }

    数据访问层:

    UserDao接口:添加用户的方式

    public interface UserDao {
    
    	public void addUser(String userName,String password);
    }

    UserDao两种实现(Mysql和Oracle):传统方式使用配置文件,然后使用工厂来创建相应的对象(即我们经常说的配置文件+抽象工厂+反射,一会儿我们再看看Spring创建对象的方式)

    public class UserDao4MysqlImpl implements UserDao{
    
    	@Override
    	public void addUser(String userName, String password) {
    		
    		//打印访问Mysql的相关信息
    		System.out.println("UserDao4MysqlImpl.addUser");
    	}
    }
    public class UserDao4OracleImpl implements UserDao{
    
    	@Override
    	public void addUser(String userName, String password) {
    		
    		//打印访问Oracle的相关信息
    		System.out.println("UserDao4OracleImpl.addUser");
    	}
    }

    运行效果图:



           看到上面的代码,非常的熟悉,因为我们平时经常使用。但是问题来了,在业务逻辑层的实现中,UserDao有多种不同的实现方式,例如Mysql和Oracle,UserManager要依赖于UserDao的具体实现。并且对象是由我们自己负责创建的,我们主动的发起了一个查找,要依赖于一种数据库的实现。此时我们的UserManager就和UserDao的具体实现紧紧的耦合在一起了我们再看客户端,我们要使用UserManager,同业务逻辑层一样,还得需要我们自己负责主动查找UserManager的具体实现。

     

          我们可以发现:传统方式,对象和对象之间发生严重的依赖关系,耦合度非常高而且依赖关系都写死在了代码里,项目不易修改和维护,必须要改代码

     

          下面我们使用Spring方式改造实例,实现同样的功能,让Spring管理我们的对象,看看Spring是怎么创建对象和描述对象之间依赖关系的。

     

    Spring方式:

     

    项目的包图:

             

    客户端:

    public class Client {
    
    	public static void main(String[] args){
    
    		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    		//到IOC容器中获取UserManager
    		UserManager userManager = (UserManager) factory.getBean("userManager");
    		//UserManager使用UserDao,在配置文件已经有依赖关系
    		userManager.addUser("jiuqiyuliang", "123456");		
    	}
    }

    业务逻辑层:
     UserManager实现:

    public class UserManagerImpl implements UserManager{
    
    	private UserDao userDao;
    
    	//使用构造方式赋值
    	public UserManagerImpl(UserDao userDao) {
    		this.userDao = userDao;
    	}
    
    	@Override
    	public void addUser(String userName, String password) {
    
    		userDao.addUser(userName, password);
    	}
    
    }

    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"
    	     xmlns:aop="http://www.springframework.org/schema/aop"
    	     xmlns:tx="http://www.springframework.org/schema/tx"
    	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
    
    	<!-- 使用spring管理对象的创建,还有对象的依赖关系 -->
    	<bean id="userDao4Mysql" class="com.tgb.spring.dao.UserDao4MysqlImpl"/>
    
    	<bean id="userDao4Oracle" class="com.tgb.spring.dao.UserDao4OracleImpl"/>
    	
    	<bean id="userManager" class="com.tgb.spring.manager.UserManagerImpl">
    		<!-- (1)userManager使用了userDao,Ioc是自动创建相应的UserDao实现,都是由容器管理-->
    		<!-- (2)在UserManager中提供构造函数,让spring将UserDao实现注入(DI)过来 -->
    		<!-- (3)让spring管理我们对象的创建和依赖关系,必须将依赖关系配置到spring的核心配置文件中 -->
    
    		<constructor-arg ref="userDao4Oracle"/>
    	</bean>
    	
    </beans>

     

           由于其他地方的代码和效果图,同上,不再浪费大家的带宽。

       

           对比传统的实现方式,再看客户端和UserManager,我们可以发现:通过IoC或DI,我们只需要通过简单的配置,而无需任何代码就可以指定UserManager中所需的UserDao的具体实现。UserManager只需利用容器注入的UserDao实例,完成自身的业务逻辑,而不用关心具体实现来自哪、由谁实现。换句话说:我们不再需要自己负责创建对象,管理对象生命周期以及维护对象的依赖关系,这些都有Spring替我们完成了。

         

    传统方式和Spring方式对比:

     

          传统方式:决定使用哪一个具体实现是由应用程序负责的,在编译阶段就确定了。

          Spring方式:调用类只依赖接口,而不依赖具体的实现类,减少了耦合。控制权交给了容器,在运行期才由容器决定将具体的实现动态的“注入”到调用类的对象中。这也是使用IoC的根本原因。

     

           现在我们对IoC有了基本认识,我们再理解一下IoC的概念。

     

    IoC

         

          IoC(Inversion of Control),控制反转,用白话来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接控制。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,就是所谓反转。

      

    IoC的优缺点

           

    优点:

    1、把对象的创建和依赖关系定义在了XML文件中,我们改变子类的实现变得异常简单。

    2、控制反转减轻了对象之间的耦合度,减轻了对象之间的依赖关系,增加了系统的灵活性,可维护性,以及可移植性等等。

    缺点:

    1、生成对象的方式变复杂了(事实上操作还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。

    2、创建对象因为使用了反射技术,在效率上有些损耗。但相对于IoC提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。

     

     总结

         IoC使得面向对象的世界更加简单,面向接口编程成为了可能。

         引言:下篇博文,我为大家转载了一篇深入理解IoC原理的博文,相当简单,通俗易通。之后,我为大家准备了一篇依赖注入几种类型对比的博文,快马加鞭ing,敬请期待。

  • 相关阅读:
    623. Add One Row to Tree 将一行添加到树中
    771. Jewels and Stones 珠宝和石头
    216. Combination Sum III 组合总数三
    384. Shuffle an Array 随机播放一个数组
    382. Linked List Random Node 链接列表随机节点
    向github项目push代码后,Jenkins实现其自动构建
    centos下安装Jenkins
    python提取批量文件内的指定内容
    批处理实现:批量为文件添加注释
    python抓取每期双色球中奖号码,用于分析
  • 原文地址:https://www.cnblogs.com/ainima/p/6330975.html
Copyright © 2011-2022 走看看