首页 > 代码库 > 模拟spring注入

模拟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=http://www.mamicode.com/"blue">>作为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 = http://www.mamicode.com/paramDefine.getPropertyValue();//注入的是String类型>
其中额注入代码有缺陷,等后期整理的更好后在弄,同时让set和map都可以,大体的结构已经设计好了。







模拟spring注入