• Spring IOC以及三种注入方式


    IOC是spring的最基础部分,也是核心模块,Spring的其他组件模块和应用开发都是以它为基础的。IOC把spring的面向接口编程和松耦合的思想体现的淋漓尽致。

    IOC概念

    IOC(Inversion of Control)译为中文“控制反转”,许多应用都是由两个或更多个类通过彼此合作来实现业务逻辑的,这使得每个对象都要引用其合作对象(也就是它所以来的对象)来装配在一起工作,而这个装配过程如果靠硬编码来实现,他们之间的耦合性有多强就可想而知的。如果把这个装配过程交给第三方(如IOC容器)来实现,那么就能很好的解耦,此时控制就反转了,反转给了第三方(如IOC容器)。

    IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种

    • 依赖查找(Dependency Lookup):容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都使用这种方式。
    • 依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

    Dependency Injection是时下最流行的IoC类型,所以有时我们说IOC的另一个名字叫依赖注入,它又有接口注入(Interface Injection),设值注入(Setter Injection)和构造子注入(Constructor Injection)三种方式。

    IOC与旧方式的对比

    本文Demo想实现的效果:架设需要之前是使用的MySql数据库,但后来却要转向Oracle数据,我们来看下使用IOC和不使用IOC的对比。当然这个例子并不合适,因为你可能立马想到Hibernate,所以请不要介意,这只是个Demo。

    1. 没有使用注入方式
      package net.oseye;
      
      public class App 
      {
          public static void main( String[] args )
          {
          	//调用数据库操作
              new MysqlHelper().insert();
          }
      }
      /**
       * Mysql数据库操作
       */
      class MysqlHelper{
      	/**
      	 * 插入数据
      	 */
      	public void insert(){
      		System.out.println("Mysql数据库插入操作");
      	}
      }
      那么如果现在转向Oracle数据库,那么你不仅要增加Oracle操作类,还必须更改调用数据库操作的代码(PS:为了演示方便,数据库操作类我没有单独文件)
      package net.oseye;
      
      public class App 
      {
          public static void main( String[] args )
          {
          	//调用数据库操作
              new OracleHelper().insert();
          }
      }
      /**
       * Mysql数据库操作
       */
      class MysqlHelper{
      	/**
      	 * 插入数据
      	 */
      	public void insert(){
      		System.out.println("Mysql数据库插入操作");
      	}
      }
      /**
       * Oracle数据库操作
       */
      class OracleHelper{
      	/**
      	 * 插入数据
      	 */
      	public void insert(){
      		System.out.println("Oracle数据库插入操作");
      	}
      }
      可见耦合性是很强的。
    2. 使用IOC的构造器注入方式
      使用IOC你能感受到面向接口编程的思想,App.java代码如下:
      package net.oseye;
      
      import org.springframework.beans.factory.BeanFactory;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class App 
      {
          public static void main( String[] args )
          {
          	//IOC容器装载Bean定义资源
      		BeanFactory beanFactory=new ClassPathXmlApplicationContext("applicationcontext.xml");
      		//依赖装配
          	IDbHelperManager idbHelperManager= beanFactory.getBean("dbhelpermanager",IDbHelperManager.class);
          	idbHelperManager.insert();
          }
      }
      /**
       * 数据库操作管理接口
       */
      interface IDbHelperManager{
      	public void insert();
      }
      /**
       * 数据库操作管理实现
       */
      class DbHelperManager implements IDbHelperManager{
      	//构造器注入准备工作
      	private IDbHelper dbHelper;
      	public DbHelperManager(IDbHelper dbHelper){
      		this.dbHelper=dbHelper;
      	}
      	
      	public void insert(){
      		this.dbHelper.insert();
      	}
      }
      /**
       * 数据库操作接口
       */
      interface IDbHelper{
      	public void insert();
      }
      /**
       * Mysql数据库操作实现
       */
      class MysqlHelper implements IDbHelper{
      	public void insert(){
      		System.out.println("Mysql数据库插入操作");
      	}
      }
      /**
       * Oracle数据库操作实现
       */
      class OracleHelper implements IDbHelper{
      	public void insert(){
      		System.out.println("Oracle数据库插入操作");
      	}
      }
      applicationcontext.xml配置文件:
      <?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 id="mysqldbhelper" class="net.oseye.MysqlHelper"></bean>
      	<bean id="oracledbhelper" class="net.oseye.OracleHelper"></bean>
      	<bean id="dbhelpermanager" class="net.oseye.DbHelperManager">
      		<constructor-arg ref="mysqldbhelper"></constructor-arg>
      	</bean>
      </beans>
      maven的pom.xml配置如下:
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      	<modelVersion>4.0.0</modelVersion>
      
      	<groupId>net.oseye</groupId>
      	<artifactId>IOCDemo</artifactId>
      	<version>1.0-SNAPSHOT</version>
      	<packaging>jar</packaging>
      
      	<name>IOCDemo</name>
      	<url>http://maven.apache.org</url>
      
      	<properties>
      		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      	</properties>
      
      	<dependencies>
      		<dependency>
      			<groupId>junit</groupId>
      			<artifactId>junit</artifactId>
      			<version>4.11</version>
      			<scope>test</scope>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework</groupId>
      			<artifactId>spring-context</artifactId>
      			<version>4.0.3.RELEASE</version>
      		</dependency>
      	</dependencies>
      </project>
      项目结构如下:

      当你想切换使用Oracle数据库,只需要修改applicationcontext.xml配置文件,把dbhelpermanager的bean配置为oracledbhelper:
      <bean id="dbhelpermanager" class="net.oseye.DbHelperManager">
      	<constructor-arg ref="oracledbhelper"></constructor-arg>
      </bean>

    依赖注入三种方式

    1. 构造器注入
      如上面Demo不在累述,构造器注入参数有值类型和引用类型(以下雷同)
      <constructor-arg ref="引用类型"></constructor-arg>
      <constructor-arg value="值类型"></constructor-arg>
    2. setter方法注入
      通过 JavaBean的属性分配依赖性,只需要修改DbHelperManager类和配置文件即可。
      class DbHelperManager implements IDbHelperManager{
      	//构造器注入准备工作
      	private IDbHelper dbHelper;
      	public void setDbHelper(IDbHelper dbHelper){
      		this.dbHelper=dbHelper;
      	}
      	
      	public void insert(){
      		this.dbHelper.insert();
      	}
      }
      applicationcontext.xml配置文件
      <?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 id="mysqldbhelper" class="net.oseye.MysqlHelper"></bean>
      	<bean id="oracledbhelper" class="net.oseye.OracleHelper"></bean>
      	<bean id="dbhelpermanager" class="net.oseye.DbHelperManager">
      		<property name="dbHelper" ref="oracledbhelper"></property>
      	</bean>
      </beans>
      这里的property要用name才能找到setter;上面通过构造器注入,因为构造器只有一个参数,所以没有使用name;
    3. 接口注入
      这种方式不常用,而且具有侵入性,暂不研究!

    三种注入方式都是将对象交与IOC容器管理,避免在程序中出现具体实现。通过代码我们可以看出IOC依赖注入的好处:

    • 对象之间的依赖关系,不由对象自身来负责,而是由容器依据配置文件动态建立,这样就很灵活,可配;
    • 采用依赖注入,模块之间一定是松散耦合的;
    • 代码易维护易测试;
    出处:http://www.zhaiqianfeng.com    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    【LA3461】Leonardo的笔记本
    【洛谷P3708】Koishi的数学题
    【Uva11762】Race to 1
    【uva11421】玩纸牌
    【反演复习计划】【51nod1594】Gcd and Phi
    【乱入】Uva11021麻球繁衍
    【反演复习计划】【bzoj4407】于神之怒加强版
    BZOJ3293: [Cqoi2011]分金币
    BZOJ2400: Spoj 839 Optimal Marks
    BZOJ1391: [Ceoi2008]order
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4620175.html
Copyright © 2020-2023  润新知