`

Spring框架之IOC&DI

阅读更多

前言:

经过一系列被鄙视后,终于拿到一份还算满意的小offer,以后的日子就是不断学习的过程了,加油。

 

最近开始学习Spring框架,现将自己目前的学习状况以及自己的一部分理解总结一下。

 

Spring框架提供给用户的有两个大的主要功能:控制反转(IOC)或依赖注入(DI)和面向切面编程(AOP),当然还提供了其他的比如操作数据库的模板化以及事务管理、web开发中的Spring MVC等,这些以后会单独总结,但是最主要的还是依赖注入和面向切面编程。

一、Spring IOC以及DI的必要性

本篇文章总结控制反转(IOC)和依赖注入(DI),两者共同解决一个问题:对象耦合问题。下面举例说明。

 

在我们访问数据库时会写DAO,假设现在需要针对不同的数据库(mysql或oracle数据库)来写DAO,于是会有一个DAO接口类,并且会有针对不同数据库的相应的实现类(MysqlDaoImpl 和 OracleDaoImpl),如下所示:

DAO接口类:

 

package com.springframework.ioc;

public interface MyDao{
	//添加
	public void addUser();
}

 mysql实现类:

 

 

package com.springframework.ioc;

public class MysqlDaoImpl implements MyDao{
	
	@Override
	public void addUser(){
		System.out.println("mysql add user...");
	}
}

 oracle实现类:

 

 

package com.springframework.ioc;

public class OracleDaoImpl implements MyDao{
	
	@Override
	public void addUser(){
		System.out.println("oracle add user...");
	}
}

 这时上层service层要调用DAO,假设我的写法如下:

 

 

package com.springframework.ioc;

public class MyService{
	
	private MyDao myDao;
	
	public MyService(){
		myDao = new MysqlDaoImpl();
	}
	
	public void addUser(){
		myDao.addUser();
	}
}
<constructor-arg ref = "oracle"/>

 这种写法的缺点就是当我要换用作oracle数据库时需要修改MyService类,将myDao的创建改为

myDao = new OracleDaoImpl();

 不符合开放-封闭原则, 于是我修改我的代码如下:

 

 

package com.springframework.ioc;

public class MyService{
	
	private MyDao myDao;
	
	public MyService(MyDao myDao){
		this.myDao = myDao;
	}
	
	public void addUser(){
		myDao.addUser();
	}
}

 这样第三方在调用service层的addUser方法时的代码如下:

 

 

package com.springframework.ioc;

public class Test{
	public static void main(String[] args){

		MyService myService = new MyService(new MysqlDaoImpl());
		myService.addUser();	
	}
}

 这样当第三方需要的是oracle数据库的操作时,只需要将自己本身的代码修改为:

 

 

MyService myService = new MyService(new OracleDaoImpl());

 

 

将myDao对象的具体创建控制权交给第三方,而另外两房不需要关心,这就叫做控制反转。

 

以上是传统的编程做法,其实Spring框架也同样为我们解决了以上问题,使用的方式就是依赖注入方式。下面采用Spring框架来实现两个对象之间的解耦。

 

在Spring框架中,每一个类对象叫做一个bean,每一个bean有一个bean id和具体的实现类,Spring的IOC容器就是对这些bean进行管理和配置,将bean与bean之间的依赖通过配置文件或者注解的方式表现出来。

 

还是以以上的例子为例,为在xml文件中配置bean并将bean和bean之间的依赖进行配置如下:

 

<?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:context="http://www.springframework.org/schema/context"
		
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
			default-lazy-init="true">
			
			<!-- beans declare go here -->
			<!-- 通过默认构造器注入 -->
			<bean id="mysql" class="com.springframework.ioc.MysqlDaoImpl"/>
			<bean id="oracle" class="com.springframework.ioc.OracleDaoImpl"/>
			<!-- 通过含参构造器注入 -->
			<bean id = "myservice" class="com.springframework.ioc.MyService">
				<constructor-arg ref = "mysql"/>
			</bean>
	</beans>

 这样就将每个类作为bean注入到spring 的IOC容器中,然后第三方就可以获取bean并实例化bean,并调用其方法。如下所示:

 

 

package com.springframework.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test{
	public static void main(String[] args){

		//传统做法
		/*MyService myService = new MyService(new OracleDaoImpl());
		myService.addUser();	*/
		
		//使用spring后的做法
		ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");
		MyService myService = (MyService)context.getBean("myservice");
		myService.addUser();
	}
}

 第三方如果想要调用的是oracle,则只需修改xml配置文件将

 

 

<constructor-arg ref = "mysql"/>

 修改为:

 

<constructor-arg ref = "oracle"/>

 即可。

将一个类通过xml配置文件的形式注入到另一个类中,实现了两个类之间的依赖,并且实现了解耦。两个类只需要关注自己的业务逻辑实现,无需管理其它类的实现。

 

二、Spring IOC&DI的实现原理

 

Spring管理bean和bean之间的依赖管理分别对应于对象的控制反转和依赖注入,控制反转即spring将xml文件进行解析,包括bean的id、class名字、别名、property属性等,解析为一个个的bean注册到IOC容器中;依赖注入即将bean通过反射的方式实例化bean,并通过三种注入方式将其他的bean注入进来,然后返回给第三方。

 

比如对于一个简单配置的spring 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"
		xmlns:context="http://www.springframework.org/schema/context"
		
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
			
			<!-- beans declare go here -->
			<!-- 通过默认构造器注入 -->
			<bean id="mysql" class="com.springframework.ioc.MysqlDaoImpl"/>
			<bean id="oracle" class="com.springframework.ioc.OracleDaoImpl"/>
	</beans>

 当Spring框架启动时,会对xml文件进行解析,按照节点首先解析的是

<bean id="mysql" class="com.springframework.ioc.MysqlDaoImpl"/>

在Spring框架中维护一个BeanDefinition来存储每一个bean节点的属性,如id、classname、propertity、autowire mode、initmethod name 、destroymethod name 等。

如下所示:

class BeanDefinition{
	//bean 的id
	private String id;
	
	//bean 的classname
	private String className;
	//bean 的init method name
        private String initMethodName;
        //等等...
}

 每有一个BeanDefinition即有一个相应的对象,内部装载着以上介绍的bean的各种属性(id、className等),然后将这些BeanDefinition对象装载到IOC容器中,内部为键值为nbeanName,值为BeanDefinition的map表,如下所示:

/** Map of bean definition objects, keyed by bean name */
	private final Map<String, BeanDefinition> beanDefinitionMap = 
                                          new ConcurrentHashMap<String, BeanDefinition>(64);

这就完成了对xml文件的解析以及对BeanDefinition实例的注册。

当调用

		MyService myService = (MyService)context.getBean("myservice");

 时,

即为从map表中根据键值beanname(即bean的id)取出BeanDefinition实例,然后通过工厂方式或者构造函数反射机制创建bean实例,然后对beandefinition中的property属性进行解析,并通过set方法或者默认构造函数实现其他bean实例的注入。

这样就将每一个类以及类与类之间的依赖以bean的形式交给Spring的IOC容器来管理。

详细的IOC&DI的源代码解析或者原理解析可以参考这篇文章 http://www.cnblogs.com/ITtangtang/p/3978349.html。

 

参考:
http://www.importnew.com/13619.html

http://www.cnblogs.com/xdp-gacl/p/4249939.html

www.cnblogs.com/ITtangtang/p/3978349.html

 

 

分享到:
评论

相关推荐

    笔记28-JAVAEE之Spring IoC&DI

    Spring IoC(Inversion of Control,即控制反转)是Spring框架的核心机制之一,它提供了一种解耦合的方式,使得应用程序的各个组件之间能够松散耦合,提高了系统的灵活性和可维护性。 在传统的编程模式中,我们通常...

    关于spring的AOP ,IOC,DI的理解

    IOC,也称为依赖注入,是Spring框架的核心概念之一。它将对象的创建和管理的权利从代码中转移给了Spring容器。在传统的Java程序中,我们通常会使用`new`关键字创建对象,但在Spring中,对象的实例化、初始化和装配都...

    02-01-07-用30个类高仿真提炼纯手写Spring框架V2.0之IOC与DI1

    Spring框架的核心特性之一是控制反转(Inversion of Control,简称IOC)和依赖注入(Dependency Injection,简称DI)。这两个概念在软件设计中起到了至关重要的作用,它们帮助开发者降低了组件之间的耦合度,提高了...

    Spring 框架的IoC

    ### Spring框架中的IoC(控制反转) 在现代软件开发中,特别是Java企业级应用领域,Spring框架因其灵活性、模块化及强大的功能支持而备受青睐。其中一个重要特性是控制反转(Inversion of Control, IoC),它是一种...

    什么是Ioc和DI

    在实际应用中,DI通常作为IoC容器的一部分来实现,例如Spring框架中的BeanFactory或ApplicationContext,它们都提供了依赖注入的功能,从而帮助开发人员遵循IoC的原则,构建出更加灵活、可维护的软件系统。...

    spring核心IOC以及DI

    【Spring核心IOC以及DI】是Spring框架中的关键概念,它们是Spring实现控制反转(Inversion of Control,简称IOC)和依赖注入(Dependency Injection,简称DI)的基石。这两个概念是Spring框架的核心,使得应用程序的...

    day38 03-Spring的IOC和DI的区别

    标题中的"Spring的IOC和DI的区别"涉及到Spring框架的核心特性,即控制反转(Inversion of Control,简称IOC)和依赖注入(Dependency Injection,简称DI)。这两个概念是理解Spring框架工作方式的关键。 首先,控制...

    Spring IOC AOP MVC 简单例子

    Spring框架是Java开发中不可或缺的一部分,它以模块化的方式提供了许多功能,如依赖注入(IOC)、面向切面编程(AOP)以及Model-View-Controller(MVC)架构模式。在本实例中,我们将深入探讨这三个核心概念以及它们...

    Spring框架IoC控制反转.pdf

    【Spring框架IoC控制反转】 一、Spring框架是什么 Spring框架是Java开发中的一款轻量级框架,诞生于2003年,旨在简化企业级应用的开发复杂性。Spring的核心理念包括控制反转(IoC)和面向切面编程(AOP)。作为一...

    IOC控制反转&DI依赖注入

    在软件开发领域,IOC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)是两种重要的设计模式,特别是在Java和Spring框架中被广泛使用。这些概念有助于提高代码的可测试性、可维护性和模块...

    springIoc实现原理

    Spring Ioc(Inversion of Control,控制反转)是Spring框架的核心特性之一,它改变了传统应用程序中对象的创建和管理方式。在传统的软件设计中,对象的创建和依赖关系的维护通常由代码自身来完成,而在Spring Ioc中...

    Spring 5.2.9的IOC核心jar包

    Spring框架是Java后端开发中的一个关键组件,尤其在依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IOC)领域,它扮演着至关重要的角色。Spring 5.2.9版本是该框架的一个稳定版本...

    SpringIoC和DI注解开发.pdf

    Spring IoC 和 DI 注解开发是 Spring 框架的核心概念,它们使得应用程序更加灵活和可扩展。数据源(连接池)是提高程序性能的一种方式,它可以在程序启动时实例化数据源,初始化部分连接资源。在使用连接资源时,从...

    java 解析xml,模拟spring框架ioc

    在Java编程领域,Spring框架是应用最广泛的轻量级框架之一,它以其强大的依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect Oriented Programming,简称AOP)功能而闻名。本教程将深入探讨如何模拟...

    Spring之IOC示例

    控制反转(IOC)是Spring框架的核心设计理念,它将对象的创建和管理权从代码中剥离出来,交由Spring容器负责。这样做的好处是解耦了应用代码与对象的生命周期管理,使得程序更易于测试和维护。 Spring实现IOC的方式...

    SpringIOC,DI+dynamic proxy 实现盗版AOP

    Spring框架是Java开发中不可或缺的一部分,它以其强大的依赖注入(DI)和控制反转(IOC)功能而闻名。本文将深入探讨如何使用Spring的IOC和DI特性,结合动态代理(Dynamic Proxy)来实现一种类似AOP(面向切面编程)...

    Spring核心学习IOC部分

    在Spring框架中,IOC(Inversion of Control,控制反转)是其核心概念之一,它改变了传统应用程序中的对象创建和管理方式。本学习资料主要聚焦于Spring的IOC容器,特别是从最基本的BeanFactory开始,逐步深入理解...

    springioc和spring aop

    Spring框架是Java开发中不可或缺的一部分,它通过提供两种核心特性——控制反转(IoC)和面向切面编程(AOP)来简化应用的构建。理解并掌握这两种技术对于任何Java开发者来说都至关重要。 **控制反转(IoC)**,也...

    Ioc, DI demo

    在Java中,Spring框架是实现IoC和DI的常用工具。 这个"IocPerformance-master"项目可能包含了基准测试代码,用于比较不同IoC容器的初始化时间、对象创建速度、内存占用等性能指标。这样的测试结果可以帮助开发者...

    Spring 的DI和IoC实例详解(转)

    在Java开发领域,Spring框架是应用最广泛的轻量级框架之一,它以其强大的依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IoC)特性深受开发者喜爱。本文将深入探讨Spring的DI和IoC...

Global site tag (gtag.js) - Google Analytics