`
Mr_Chunlei
  • 浏览: 29800 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

模拟spring注入

 
阅读更多

尊重原创:原创和源代码地址

项目中的的spring出现问题,不想使用spring框架进行注入,编写一个简单的spring,实现xml解析和类的注入。所有的框架都可以用java项目,用到了java提供的基础类,所以用到的原理也就呢么多(我刚开始工作2个月,说的不对请谅解)。因此spring用到了注入用到java中的反射机制,aop用到了java的代理机制proxy对象。总结一下自己的设计:

设计范围三层:

第一层是实体层,根据自己定义的xml规则抽象除了两个对象实体,一个是实体对象bean(程序中定义为BeanDefineModel),另一个是属性实体对象(程序中定义为ParamDefineModel)。

第二层是xml解析层,既将xml进行解析,生成beanDefineFactory对象的连。(这里采用的第三方的dom4j的jar包)进行解析,将xml解析成一个一个的对象链。

第三层是实例化,并对实例化的对象进行属性注入。ApplicationContext


(本模拟spring用到了dom4j.jar还有commom.collection.jar和common.lang.jar)源码在后面资源中提供。所有的框架开始是定义xml规范,对规范的内容进行解析注入,最终生成一个访问bean的hashMap的接口,xml格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--@author chunlei 原创:url-->
<beans>
    <bean name="blueHair" class ="com.test.source.Hair">
    	<property name="color" value="blue"></property>
    	<property name="hair" value="good"></property>
    	<property name="stringList">
    		<list>
    			<li value="zhang"></li>
    			<li value="chun"></li>
    		</list>
    	</property>
    </bean>
   <bean name ="body" class ="com.source.Body">
		<property name="name" value="zhang"></property>
		<property name="hair" ref="blueHair"></property>
    </bean>
</beans>  
作为bean标签只有name 和class当然后期你可以加上type等属性,不过需要对model解析进行修改,property的属性定义为name,value,ref,list,map,和set。map和set的没有实现,其他的都实现了,会抽时间继续填补自己的框架。其中list标签必须以li来开头,这样li下面可以存在name,value,ref,list等属性,实现param的model的重用。同样在解析和实例化的时候可以使用递归。

在完成这个任务时遇到问题就是在注入的地方,因为利用反射机制寻找到方法可以使用method(methodName,propertyType)来获得方法,不过容易报错,因为我们在xml中注入的时候有可能使用实体类注入,有可能使用接口注入。后来使用了比较麻烦的办法,先拼接方法名,然后获得bean的所有方法,遍历所有的方法根据方法名找到方法,然后找到方法的参数类型,判断是否和注入属性是否相同,若相同则直接调用反射机制进行注入,若不同则得到参数的所有接口,遍历接口判断是否和参数接口相同来进行注入,具体的代码如下:,最终代码在公司,没有拿来,现在的代码是自己回来加班做的,只考虑到实体类注入,下发上去,后期会修改。资源在后面分享,中秋节的时间排满了,还要看solr的源代码等,作业很多。谅解。重要代码,递归注入:

<pre name="code" class="java">package com.test;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

public class ApplicationContext{
	
	private static HashMap<String,Object> hashMap = new HashMap<String,Object>();//用来存放bean对象
	
	public static HashMap<String,Object> getBeanMap(String xmlPath){
		List<BeanDefine> beanDefineList = BeanDefineFactory.getBeanDefineList(xmlPath);//获得beanDefineList的
		if(CollectionUtils.isNotEmpty(beanDefineList)){
			for(BeanDefine beanDefine : beanDefineList){//遍历beanDefineList获得所有的beanDefine
				if(beanDefine != null){
					String beanName = beanDefine.getBeanName();//以beanName作为key放到beanMap中
					Object object = getBeanObject(beanDefine);//将beanDefine转化为bean对象
					hashMap.put(beanName, object);
				}
			}
		}
		return hashMap;
	}
	
	public static Object getBeanObject(BeanDefine beanDefine){
		String beanClass = beanDefine.getBeanClass();//获得bean的类型
		Object beanObject = getObjectByClass(beanClass);//根据bean对象获得对象
		List<ParamDefine> paramDefineList = beanDefine.getPropertyList();//bean获取propertyList
		if(CollectionUtils.isNotEmpty(paramDefineList)){
			for(ParamDefine paramDefine : paramDefineList){//遍历属性列表进行注入
				if(paramDefine != null){
					String paramName = paramDefine.getPropertyName();
					Object paramObject = getParamObject(paramDefine);//获得paramDefine对象
					beanObject = getRegistBeanObject(beanObject,paramName,paramObject);//注入bean对象
				}
			}
		}
		return beanObject;
	}
	
	public static Object getParamObject(ParamDefine paramDefine){
		Object paramObject = null;
		String paramValue = paramDefine.getPropertyValue();//注入的是String类型
		if(StringUtils.isNotEmpty(paramValue)){
			paramObject = new String(paramValue);
			return paramObject;
		}
		String propertyRef = paramDefine.getPropertyRef();//判断注入是否Ref类型
		if(StringUtils.isNotEmpty(propertyRef)){
			if(hashMap.containsKey(propertyRef)){
				paramObject = hashMap.get(propertyRef);
			}
			return paramObject;
		}
		List<ParamDefine> paramDefineList = paramDefine.getList();//判断注入是否List类型
		if(CollectionUtils.isNotEmpty(paramDefineList)){
			List<Object> list = new LinkedList<Object>();
			for(ParamDefine tempParamDefine : paramDefineList){
				Object tempParamObject = getParamObject(tempParamDefine);
				list.add(tempParamObject);
			}
			return paramObject = list;
		}
//		Set<ParamDefine> paramDefineSet = paramDefine.getSet();//判断注入是否Set类型
//		if(CollectionUtils.isNotEmpty(paramDefineList)){
//			object = registObjectBySet(object,paramName,paramDefineList);
//			return object;
//		}
//		Map<String,ParamDefine> paramDefineMap = paramDefine.getMap();//判断是否是Map类型
//		if(paramDefineMap != null && paramDefineMap.size() !=0){
//			object = registObjectByMap(object,paramName,paramDefineMap);
//			return object;
//		}
		return paramObject;
	}
	
	/**
	 * 使用java反射机制对bean对象进行注入
	 * @param beanObject bean对象
	 * @param paramName 属性名称
	 * @param paramObject 属性参数
	 * @return
	 */
	public static Object getRegistBeanObject(Object beanObject,String paramName,Object paramObject){
		 String methodName = "set" + paramName.substring(0,1).toUpperCase()+paramName.substring(1);//获取方法的名称
		 System.out.println(paramObject.getClass().toString());
		 System.out.println(methodName);
		 try {
			Method method = beanObject.getClass().getMethod(methodName, paramObject.getClass());//通过class类型,方法名和参数类型来获得方法
			method.invoke(beanObject,paramObject);//java反射调用set方法,进行属性设置
			 } catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 return beanObject;
	}
	
	/**
	 * 根据xml中bean的class属性值来创建bean对象:这里的bean对象时未被设置属性的对象
	 * @param classNamee
	 * @return
	 */
	public static Object getObjectByClass(String beanClass){//根据ClassName生成对象
		Object beanObject = null;
		try {
			beanObject = Class.forName(beanClass).newInstance();//调用class驱动实例化对象
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return beanObject;
	}
}

其中额注入代码有缺陷,等后期整理的更好后在弄,同时让set和map都可以,大体的结构已经设计好了。








分享到:
评论

相关推荐

    使用反射和注解模拟Spring的依赖注入

    这篇博客"使用反射和注解模拟Spring的依赖注入"探讨了如何通过基本的Java特性来实现类似Spring的功能。我们将深入探讨反射和注解这两个关键概念,以及它们如何在模拟依赖注入中发挥作用。 首先,让我们理解反射的...

    自己的代码模拟spring的依赖注入

    现在,我们将深入探讨如何通过自己的代码来模拟Spring的依赖注入。 首先,理解依赖注入的概念至关重要。依赖注入意味着组件不直接创建其依赖的对象,而是由外部实体(如Spring IoC容器)提供。这样做的好处是,我们...

    模拟Spring的依赖注入

    本篇文章将深入探讨如何通过Java代码来模拟Spring的依赖注入机制。 **依赖注入的概念** 依赖注入是一种设计模式,它允许对象在运行时获取其依赖项,而不是在构造函数或初始化方法中硬编码这些依赖项。这样做的好处...

    以注解方式模拟Spring IoC AOP

    本篇将深入探讨如何通过注解方式来模拟Spring的这两种机制,帮助你理解其底层原理。 ### 1. 依赖注入(IoC) 依赖注入是Spring框架的核心特性之一,它通过反转对象创建和管理的控制权,使得应用程序组件之间的耦合...

    模拟spring依赖注入

    模拟Spring的依赖注入,旨在理解其核心机制,让我们一起深入探讨这一主题。 首先,我们要明白什么是依赖注入。在传统的编程中,一个对象通常会直接创建或查找它所依赖的对象,这会导致类之间的紧密耦合。依赖注入则...

    Spring简单模拟Spring容器

    标题中的“Spring简单模拟Spring容器”意味着我们将探讨Spring框架的核心特性——IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入),以及如何通过编程方式模拟Spring容器的工作原理。...

    模拟Spring的IOC

    **模拟Spring的IOC** 在Java世界中,Spring框架以其强大的依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IOC)能力,成为企业级应用开发的首选框架之一。理解并模拟Spring的IOC...

    Java模拟spring实现

    在本文中,我们将探讨如何通过Java来模拟Spring框架的基本功能。Spring是一个广泛应用的开源框架,它主要为Java应用程序提供依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP...

    java模拟spring ioc

    这篇博客“java模拟spring ioc”很可能是探讨如何在没有Spring框架的情况下,使用纯Java代码来实现类似Spring的IOC功能。以下将详细介绍Spring的IOC和DI概念以及如何模拟这些概念。 **依赖注入(Dependency ...

    自己动手模拟spring

    【标题】:“自己动手模拟spring” 【描述】:在该主题中,我们将深入理解Spring框架的核心概念,并通过编码实践来模拟其工作原理。参考链接提供了一个CSDN博客文章,作者详细介绍了如何从零开始创建一个简易版的...

    模拟spring的xml配置文件注入

    本文将深入探讨如何模拟Spring的XML配置文件注入,并通过SAXBuilder解析XML文件来实现这一过程。 首先,理解XML配置文件在Spring中的作用至关重要。XML配置文件用于声明应用程序中的bean及其依赖关系,例如类的实例...

    模拟spring

    《模拟Spring:深入理解与实践》 在软件开发领域,Spring框架无疑是最为广泛使用的Java企业级应用框架之一。它以其强大的依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)...

    模拟Spring IoC

    在这个模拟Spring IoC的项目中,我们可以深入理解以下几个关键知识点: 1. **容器的概念**:Spring IoC容器是管理对象及其依赖关系的核心组件。在这个模拟项目中,会有一个类或接口扮演容器的角色,负责创建对象、...

    模拟spring ioc过程

    这个"模拟spring ioc过程"的学习例子是基于Java语言的,旨在帮助理解Spring框架中的这两个核心概念。在Java工程中,我们通常会通过配置文件(如XML或Java配置类)来定义bean的定义和它们之间的依赖关系。在实际运行...

    模拟spring和工具jar包

    本资源名为“模拟spring和工具jar包”,其目的是为了帮助我们理解Spring框架的核心概念——依赖注入,并通过一个简化版的实现来学习这一机制。 依赖注入是Spring框架的核心特性之一,它允许我们在不直接创建对象的...

    java 解析xml,模拟spring框架ioc

    模拟Spring的IOC功能,我们可以创建一个简单的解析器类,该类负责加载XML配置文件,解析Bean定义,实例化和注入依赖。为了实现这个功能,我们需要了解和使用Java的DOM或SAX解析库,以及反射API。这是一个很好的学习...

    简单模拟Spring的beanFactory

    本文将通过模拟Spring的`BeanFactory`来深入理解其工作原理,帮助开发者更好地掌握Spring的核心概念。 `BeanFactory`是Spring框架中最基础的bean管理容器,它是所有更高级别的容器(如`ApplicationContext`)的基类...

    尚学堂_Spring_0100_模拟Spring

    《尚学堂_Spring_0100_模拟Spring》 在深入探讨Spring框架之前,我们需要先理解Spring的核心理念。Spring是一个开源的Java平台,它主要为构建企业级应用提供了全面的编程和配置模型。它的核心特性是依赖注入...

    模拟Spring架构的简易实现

    总的来说,这个"模拟Spring架构的简易实现"项目是一个很好的学习工具,可以帮助开发者深入理解Spring框架的工作原理,尤其是依赖注入和面向切面编程的概念。通过实际动手操作,可以更好地掌握这些核心概念,并为实际...

    一个模拟Spring将SessionFactory注入到HibernateTemplate的小例子

    在Spring框架中,整合Hibernate是常见的操作,Spring通过其强大的依赖注入(DI)特性,能够帮助我们更好地管理和控制SessionFactory以及与Hibernate相关的操作。本示例将深入探讨如何使用Spring将SessionFactory注入...

Global site tag (gtag.js) - Google Analytics