spring IOC的实现原理

姓名:罗秀群    班级:软件151

IOC的意思是控件反转也就是由容器控制程序之间的关系,把控件权交给了外部容器,之前的写法,由程序代码直接操控,而现在控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。

 IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
下面来模拟下IOC和DI的实现原理。

1、首先定义DAO接口和接口的实现类
package com.dao;

public interface PersonDAO {
	public void save();
}

 

  1. package com.dao.impl;
  2. import com.dao.PersonDAO;
  3. public class PersonDaoImpl implements PersonDAO {
  4. @Override
  5. public void save() {
  6. System.out.println("保存");
  7. }
  8. }
2、创建一个Junit测试类
package com.test;

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

import com.dao.PersonDAO;
import com.myUtil.MyClassPathXmlApplicationContext;
import com.service.PersonService;

public class PersonTest {

	@Test
	public void instanceSpring1(){
		/**
		 *
		 * spring 的实现
		 */
		//IOC
		ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
		PersonDAO pd = (PersonDAO) ac.getBean("personDAO");
		pd.save();
		//DI
		PersonService ps = (PersonService) ac.getBean("personService");
		ps.save();
	}

	@Test
	public void instanceSpring2(){

		/**
		 * 我的实现
		 *
		 */
		MyClassPathXmlApplicationContext mac = new MyClassPathXmlApplicationContext("beans.xml");
		PersonDAO mpd = (PersonDAO) mac.getBean("personDAO");
		mpd.save();
		//DI
		PersonService ps = (PersonService) mac.getBean("personService");
		ps.save();
	}

}
方法instanceSpring1为Spring中的实现用到ClassPathXmlApplicationContext类,要实现IOC的原理要定义自己的MyClassPathXmlApplicationContext首先读出beans.xml中的配置信息,通过反射机制实现bean,最后注入所需要的bean。
package com.myUtil;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class MyClassPathXmlApplicationContext {
	// xml所有的属性
	private ArrayList<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
	// xml中所有的bean
	private Map<String, Object> sigletons = new HashMap<String, Object>();

	public MyClassPathXmlApplicationContext(String file) {
		readXml(file);
		instanceBeans();
		instanceObject();
	}

	/**
	 * 注入
	 */
	private void instanceObject() {
		for (BeanDefinition beanDefinition : beanDefinitions) {
			//判断有没有注入属性
			if (beanDefinition.getProperty() != null) {
				Object bean = sigletons.get(beanDefinition.getId());
				if (bean != null) {
					try {
						//得到被注入bean的所有的属性
						PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
						//得到所有的注入bean属性
						for(PropertyDefinition propertyDefinition:beanDefinition.getProperty()){
							for(PropertyDescriptor propertyDescriptor:ps){
								if(propertyDescriptor.getName().equals(propertyDefinition.getName())){
									Method setter = propertyDescriptor.getWriteMethod();//获取set方法
									if(setter!=null){
										setter.setAccessible(true);//得到private权限
										//注入属性
										setter.invoke(bean, sigletons.get(propertyDefinition.getRef()));
									}
									break;
								}
							}
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * 实例所有的bean
	 */
	private void instanceBeans() {
		for (int i = 0; i < beanDefinitions.size(); i++) {
			BeanDefinition bd = beanDefinitions.get(i);
			try {
				try {
					if (bd.getClassName() != null
							&& !bd.getClassName().equals(""))
						sigletons.put(bd.getId(), Class.forName(
								bd.getClassName()).newInstance());
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 读xml
	 *
	 * @param file
	 */
	private void readXml(String file) {
		try {
			SAXReader reader = new SAXReader(); // 使用SAX方式解析XML
			URL xmlPath = this.getClass().getClassLoader().getResource(file);
			Document doc = reader.read(xmlPath);
			Element root = doc.getRootElement(); // 取得根节点
			List<Element> beans = root.elements();
			for (Element element : beans) {
				String id = element.attributeValue("id");// id;
				String clazz = element.attributeValue("class");
				BeanDefinition bd = new BeanDefinition(id, clazz);
				// 读取子元素
				if (element.hasContent()) {
					List<Element> propertys = element.elements();
					for (Element property : propertys) {
						String name = property.attributeValue("name");
						String ref = property.attributeValue("ref");
						PropertyDefinition pd = new PropertyDefinition(name,
								ref);
						bd.getProperty().add(pd);
					}
				}
				beanDefinitions.add(bd);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	/**
	 * 通过名字得到bean
	 *
	 * @param str
	 * @return
	 */
	public Object getBean(String str) {
		return sigletons.get(str);
	}

}
读取所的bean实体

 

package com.myUtil;

import java.util.ArrayList;
import java.util.List;

public class BeanDefinition {
	private String id;
	private String className;
	private List<PropertyDefinition> property = new ArrayList<PropertyDefinition>();

	public BeanDefinition(String id, String className) {
		super();
		this.id = id;
		this.className = className;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public List<PropertyDefinition> getProperty() {
		return property;
	}

	public void setProperty(List<PropertyDefinition> property) {
		this.property = property;
	}

}
注入属性实体
package com.myUtil;

public class PropertyDefinition {
	private String name;
	private String ref;

	public PropertyDefinition(String name, String ref) {
		this.name = name;
		this.ref = ref;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRef() {
		return ref;
	}

	public void setRef(String ref) {
		this.ref = ref;
	}

}
业务接口和实现类
package com.service;

public interface PersonService {
	public void save();
}
package com.service.impl;

import com.dao.PersonDAO;
import com.service.PersonService;

public class PersonServiceImpl implements PersonService{
	private PersonDAO pdo;

	public PersonDAO getPdo() {
		return pdo;
	}

	public void setPdo(PersonDAO pdo) {
		this.pdo = pdo;
	}

	@Override
	public void save() {
		pdo.save();
	}

}
beans.xml配置
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  6. <bean id="personDAO" class="com.dao.impl.PersonDaoImpl"></bean>
  7. <bean id="personService" class="com.service.impl.PersonServiceImpl">
  8. <property name="pdo" ref="personDAO"></property>
  9. </bean>
  10. </beans>



 
时间: 2024-11-09 16:23:17

spring IOC的实现原理的相关文章

spring ioc aop 的原理

IOC(反转控制):对成员变量的赋值的控制权从代码中反转到配置文件中.AOP:Aspect(切面) Oriented(面向) Programming(编程),面向切面编程.差不多就够了,再看就是Spring的事务处理,基本就这些.

Spring IOC, DI, AOP 原理和实现

介绍的比较详细(概念): http://blog.csdn.net/mdcmy/article/details/8542277 http://my.oschina.net/u/1012289/blog/136648 系统的学习: http://openhome.cc/Gossip/SpringGossip/

spring ioc aop 原理

spring ioc aop 原理 spring ioc aop 的原理 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分. 在传统的程序设计中,当调用者需要被调用者的协助时,通常由调用者来创建被调用者的实例.但在spring里创建被调用者的工作不再由调用者来完成,因此控制反转(IoC):创建被调用者实例的工作通常由spring容器来完成,然后注入调用者,因此也被称为依赖注入(DI),依赖注入和控制反转是同一个概念. 面向方面编程(AOP)是以另

自我分析-Spring IOC

Spring IOC容器实现原理大致是容器(Map)+反射(Java反射和cglib).Spring提供丰富的ApplicationContext,以FileSystemXmlApplicationContext来分析IOC容器. 代码中大量使用设计模式-模板模式,若不清楚请先看看模板模式再来看具体分析.分析框架代码时要 多使用查看类继承和调用关系快捷键,快捷键可以设置,我是设置为F1和F4. 注意: 1.本文重在怎么自我分析框架代码,所以对其中解析需自己实际跟踪代码实践方可. 2.spring

Spring IoC底层原理

-------------------siwuxie095 Spring IoC 底层原理 1.IoC 即 Inversion of Control,控制反转,把对象的创建 交给 Spring 进行管理 2.IoC 容器管理 Bean 的方式: (1)基于配置文件的方式 (2)基于注解的方式 3.IoC 底层原理所使用的技术: (1)XML 配置文件 (2)dom4j 解析 XML (3)工厂模式 (5)反射 4.原始方案,耦合度太高 public class UserService{ publ

Spring:源码解读Spring IOC原理

Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. IoC容器的初始化 1. XmlBeanFactory(屌丝IOC)的整个流程 2. FileSystemXmlApplicationContext 的IOC容器流程 1.高富帅IOC解剖 2. 设置资源加载器和资源定位 3.AbstractApplicationContext的refresh函数载入

Spring IOC原理(初级版)

Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开发.从简单性.可测试性和松耦合性的角度而言,绝大部分Java应用都可以从Spring中受益. ------------------------------------------------------------↑ 以上都是废话,我也不懂 ↑   ↓ 下面是整体架构,可以略过 ↓ ----------------------

【Spring】Spring IOC原理及源码解析之scope=request、session

一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存放什么东西的意思,但是放在程序猿的世界,却注定是千差万别.Collection,集合,存放obj instanceof Class为true的一类对象,重点在于存放:Container,容器,可以存放各种各样的obj,但不仅仅是存放,他被称为容器,更重要的是他能管理存放对象的生命周期和依赖. 容器:

Spring——IoC原理

一.概念 IoC是Inversion of Control的缩写,有的翻译成"控制反转",还有翻译为"控制反向"或者"控制倒置". 二.什么是IoC IoC就是IoC,不是什么技术,与GoF一样,是一种设计模式.在Spring中控制反转是Spring框架的核心,其原理是基于OO设计原则的:Don't call us,we'll call you(别来找我,我会来找你的).也就是说,所有组件都是被动的,所有的组件初始化和调用都由容器负责.组件处在一