`
zhouxingfu520
  • 浏览: 422904 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

spring深入源码1 简单实现ioc机制

阅读更多

用spring也有两年多了 最近一段时间一直在看框架的源代码 从连接池,tomcat到spring 从中学到最多的是代 模式,java反射,设计思想。

 

我们不但要知其然,还要知其所以然。“知其所以然”的最好 办法就是下载源代码,仔细研读,揣摩并领会源代 码的精义,看看这些经过诸多高手修改的源代码究竟藏有什么玄机,我们能从其中学习到哪些设计思想及设计模式,代码架构如何等,我们从源代码中学习的东西太多了。

 

下面我根据spring源码 简单实现自己的依赖注入  通过xml形式配置   在对象中获取xml文件 获取定义好的bean 从而对bean对应的class 实现实例化   使用接口形式

 

接口

 

public interface PersonDao {

	public void add();

}
 

实现类

package cn.leam.dao.impl;

import cn.leam.dao.PersonDao;

public class PersonDaoBean implements PersonDao {
	public void add(){
		System.out.println("执行add()方法");
	}
}
 

服务接口

public interface PersonService {

	public void save();

}

 

服务实现类

public class PersonServiceBean implements PersonService {
	private PersonDao personDao;
	
	public PersonDao getPersonDao() {
		return personDao;
	}

	public void setPersonDao(PersonDao personDao) {
		this.personDao = personDao;
	}
	
	public void save(){
		personDao.add();
	}
}
 

 

首先配置beans.xml    配置DAO,SERVICE实现类

 

<?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-2.5.xsd">
           <bean id="personDao" class="cn.leam.dao.impl.PersonDaoBean"></bean>
          <bean id="personService" class="cn.leam.service.impl.PersonServiceBean">
          	<property name="personDao" ref="personDao"></property>
          </bean>
</beans>
 

 

 

下面模拟spring对xml配置的类进行实例化

 

存放属性的对象

public class prosDefinition {
	private String name;
	private String ref;
	
	public ProsDefinition(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;
	}
	
}
 

 

存放bean的 对象

public class Definition {
	private String id;
	private String className;
	private List<ProsDefinition> propertys = new ArrayList<ProsDefinition>();
	
	public Definition(String id, String className) {
		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> getPropertys() {
		return propertys;
	}
	public void setPropertys(List<PropertyDefinition> propertys) {
		this.propertys = propertys;
	}
	
}
 

 

这里是关键点  所有代码都在这里    使用dom4j 解析xml文件中的bean  并获取id和class  再判断元素中是否有引用元素对其一并获取出来存放才Map中 利用java反射一个一个进行实例化

/**
 * 学习版容器
 *
 */
public class LeamClassPathXMLApplicationContext {
	private List<Definition> beanDefines = new ArrayList<Definition>();
	private Map<String, Object> sigletons = new HashMap<String, Object>();
	
	public LeamClassPathXMLApplicationContext(String filename){
		this.readXML(filename);
		this.instanceBeans();
		this.injectObject();
	}
	/**
	 * 为bean对象的属性注入值
	 */
	private void injectObject() {
		for(Definition beanDefinition : beanDefines){
			Object bean = sigletons.get(beanDefinition.getId());
			if(bean!=null){
				try {
					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass())
                                                      .getPropertyDescriptors();
					for(ProsDefinition propertyDefinition : beanDefinition.getPropertys()){
						for(PropertyDescriptor properdesc : ps){
						if(propertyDefinition.getName().equals(properdesc.getName())){
								Method setter = properdesc.getWriteMethod();
                                    //获取属性的setter方法 ,private
								if(setter!=null){
								Object value = sigletons.get(propertyDefinition.getRef());
								setter.invoke(bean, value);//把引用对象注入到属性
								}
								break;
							}
						}
					}
				} catch (Exception e) {
				}
			}
		}
	}
	/**
	 * 完成bean的实例化
	 */
	private void instanceBeans() {
		for(Definition beanDefinition : beanDefines){
			try {
				if(beanDefinition.getClassName()!=null && !"".
                                   equals(beanDefinition.getClassName().trim()))
	                          sigletons.put(beanDefinition.getId(), 
                                  Class.forName(beanDefinition.getClassName()).newInstance());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	/**
	 * 读取xml配置文件
	 * @param filename
	 */
	private void readXML(String filename) {
	       SAXReader saxReader = new SAXReader();   
	        Document document=null;   
	        try{
	         URL xmlpath = this.getClass().getClassLoader().getResource(filename);
	         document = saxReader.read(xmlpath);
	         Map<String,String> nsMap = new HashMap<String,String>();
	         nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间
                 //创建beans/bean查询路径      
                XPath xsub = document.createXPath("//ns:beans/ns:bean");
	         xsub.setNamespaceURIs(nsMap);//设置命名空间
	         List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点 
	         for(Element element: beans){
	            String id = element.attributeValue("id");//获取id属性值
	            String clazz = element.attributeValue("class"); //获取class属性值        
	            Definition beanDefine = new Definition(id, clazz);
	            XPath propertysub =  element.createXPath("ns:property");
	            propertysub.setNamespaceURIs(nsMap);//设置命名空间
	            List<Element> propertys = propertysub.selectNodes(element);
	            for(Element property : propertys){	            	
                        //元素内部引用的属性也获取
	            	String propertyName = property.attributeValue("name");
	            	String propertyref = property.attributeValue("ref");
	            	ProsDefinition propertyDefinition = 
                         new ProsDefinition(propertyName, propertyref);
	            	beanDefine.getPropertys().add(propertyDefinition);
	            }
	            beanDefines.add(beanDefine);
	         } 
	        }catch(Exception e){   
	            e.printStackTrace();
	        }
	}
	/**
	 * 获取bean实例
	 * @param beanName
	 * @return
	 */
	public Object getBean(String beanName){
		return this.sigletons.get(beanName);
	}
}

 

上面简单的依赖注入 基本完成 当然spring的源码会管家复杂  我们主要是理解其思想  下面我们来测试

 

public class SpringTest {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@Test public void instanceSpring(){
		LeamClassPathXMLApplicationContext ctx = new
                                      LeamClassPathXMLApplicationContext("beans.xml");
		PersonService personService = (PersonService)ctx.getBean("personService");
		personService.save();		
	}
}

 

 

 

最终输出 说明实例化成功

 

执行add()方法

分享到:
评论

相关推荐

    Spring源码分析_Spring_IOC

    ### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...

    Spring IoC源码深度剖析开源架构源码2021.pdf

    5. **搭建Spring源码阅读环境** - 从GitHub下载Spring框架的源码。 - 安装和配置 `gradle`、Idea等开发工具。 - 根据Spring的模块结构编译源码,通常需要按照 `core-oxm-context-beans-aspects-aop` 的顺序进行。...

    spring_ioc

    这是spring_ioc部分的内容。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。...

    Spring IOC源码解读

    Spring IOC,即Inversion of Control(控制反转),是Spring框架的核心特性之一,它负责管理和装配应用程序中的对象。...理解并掌握Spring的IOC源码,对于深入学习Spring框架以及提升系统设计能力具有重要意义。

    Spring ioc源码解读

    通过对Spring IoC容器的理解和源码分析,我们可以深入了解到Spring框架是如何管理和控制应用对象的生命周期及依赖关系的。在实际开发中,了解Spring IoC容器的工作原理有助于更好地利用Spring框架,提高开发效率和...

    深入解析Spring IoC源码:核心机制与实践应用

    《深入解析Spring IoC源码:核心机制与实践应用》 Spring框架的IoC(Inversion of Control,控制反转)是其核心特性之一,它极大地简化了Java应用程序的开发。本文将深入剖析Spring IoC容器的源码,揭示其工作原理...

    Spring4 IOC 示例源码

    在这个示例源码中,我们可以深入理解并学习如何在实际项目中运用Spring的IOC容器来管理对象的生命周期和依赖关系。 1. **Spring 框架介绍** Spring是一个开源的Java平台,它提供了全面的企业级应用开发解决方案,...

    SpringIoC的简单实现

    我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理和源码。 详细内容见博文: 【SSH进阶之路】一步步重构容器实现Spring的IoC——从一个...

    Spring源码分析.pdf

    在 Spring 框架中,IOC 容器扮演着核心角色,本文将深入分析 Spring 源码,了解 IOC 容器的实现机制和基本原理。 一、IOC 容器 IOC容器是 Spring 框架的核心组件之一,它提供了一个统一的方式来管理应用程序中的...

    Spring AOP IOC源码笔记.pdf

    本笔记将深入探讨这两个概念以及它们在Spring中的实现。 1. Spring框架简介: Spring作为一个轻量级的开源框架,旨在简化企业级应用的开发。它通过提供IOC容器,实现了对象的创建、管理和依赖注入,减轻了开发者对...

    spring ioc

    标题 "Spring IOC" 描述了我们讨论的核心主题——Spring 框架中的依赖注入(Inversion of Control,简称 IOC)机制。Spring 是一个广泛应用的 Java 应用开发框架,其核心特性之一就是IOC,它极大地简化了软件组件...

    基于Maven构建的Spring IoC源码实例

    在"基于Maven构建的Spring IoC源码实例"中,我们可以学到如何使用Maven搭建Spring项目,并通过Spring IoC实现组件间的依赖注入。以下是这个实例中可能包含的关键知识点: 1. **Maven项目结构**:了解标准的Maven...

    spring1.2.6源码

    了解这两者的实现机制,有助于理解Spring如何在运行时创建和增强目标对象。 7. **事件驱动**:Spring框架支持事件发布和监听,`ApplicationEvent`和`ApplicationListener`接口是实现这一功能的关键。 通过阅读和...

    Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程.doc

    Spring 框架系列(7)- Spring IOC 实现原理详解之 IOC 初始化流程 本文将详细解释 Spring 框架中的 IOC(Inversion of Control,控制反转)实现原理之 IOC 初始化流程。IOC 是一种软件设计模式,用于将软件系统中...

    spring 源码中文注释

    在源码分析的过程中,读者会深入理解Spring的内部工作机制,例如如何解析配置、如何创建bean实例、如何实现AOP代理等。这将有助于开发者编写更高效、更健壮的代码,也能为参与Spring的扩展或定制打下坚实基础。 总...

    模拟Spring的IOC

    理解并模拟Spring的IOC机制对于深入学习Spring以及提升软件设计能力具有重要意义。 **1. 控制反转(IOC)概念** 控制反转是一种设计思想,它将对象的创建和管理权交给容器,而不是由对象自身负责。这样可以降低对象...

    spring4源码1

    描述中的"spring4 -1"可能是课程或者资料的编号,暗示我们将从基础开始深入学习Spring 4的源码。 标签"spring"进一步确认了我们的主题,即Spring框架。Spring框架是Java开发者的常用工具,它的灵活性和广泛的功能...

    Spring5 源码分析(第 2 版)-某Tom老师

    《Spring5 源码分析(第 2 版)》是某Tom老师精心编写的深度解析文档,旨在帮助读者全面理解Spring5的核心机制和设计理念。Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇...

    简单记录spring 实现IOC的流程

    在这个简单的记录中,我们将深入理解Spring如何实现IOC的流程,以及这一过程对软件开发的影响。 首先,我们需要明确什么是IOC和DI。在传统的编程模式中,开发者需要在代码中手动创建对象并管理它们的生命周期。而...

Global site tag (gtag.js) - Google Analytics