单手写Spring系列 (5) DI

 

原始框架赋值

 

 

模拟依赖注入

1、实体

属性待注入


public class Teacher {
	  
    private  String teacherName;
    private  String friendArray[];
    private  List<String>   school;
	public String getTeacherName() {
		return teacherName;
	}
	public void setTeacherName(String teacherName) {
		this.teacherName = teacherName;
	}
	public String[] getFriendArray() {
		return friendArray;
	}
	public void setFriendArray(Object friendArray) {
		this.friendArray = (String[])friendArray;
	}
	public List<String> getSchool() {
		return school;
	}
	public void setSchool(List<String> school) {
		this.school = school;
	}
    
    
   
}

增加map存放属性

2、beandefine

注入:propertyMap


import java.util.HashMap;
import java.util.Map;

public class BeanDefined {
	/*
	 * 
	 *   
	 *   <bean id  ,class,  scope.factory-bean,factory-method>
	 **/
	private String beanId;
	private String classPath;
	private String scope ="singleton";
	private String factoryBean=null;
	private String factoryMethod=null;
	private Map<String,String> propertyMap=new HashMap();
	
	
	public Map<String, String> getPropertyMap() {
		return propertyMap;
	}
	public void setPropertyMap(Map<String, String> propertyMap) {
		this.propertyMap = propertyMap;
	}
	public String getFactoryBean() {
		return factoryBean;
	}
	public void setFactoryBean(String factoryBean) {
		this.factoryBean = factoryBean;
	}
	public String getFactoryMethod() {
		return factoryMethod;
	}
	public void setFactoryMethod(String factoryMethod) {
		this.factoryMethod = factoryMethod;
	}
	public String getScope() {
		return scope;
	}
	public void setScope(String scope) {
		this.scope = scope;
	}
	public String getBeanId() {
		return beanId;
	}
	public void setBeanId(String beanId) {
		this.beanId = beanId;
	}
	public String getClassPath() {
		return classPath;
	}
	public void setClassPath(String classPath) {
		this.classPath = classPath;
	}
	
	

}

 

3、BeanPostProcessor增强处理

public class MyBeanPostProcessor implements BeanPostProcessor {

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
		System.out.println("bean对象初始化之前。。。。。");
		return bean;
		//return  bean对象监控代理对象
	}

	public Object postProcessAfterInitialization(final Object beanInstance, String beanName) throws Exception {
		// 为当前bean对象注册代理监控对象,负责增强bean对象方法能力
		Class beanClass = beanInstance.getClass();
		if (beanClass == ISomeService.class) {
			Object proxy = Proxy.newProxyInstance(beanInstance.getClass().getClassLoader(),
					beanInstance.getClass().getInterfaces(), new InvocationHandler() {
						/*
						 * 
						 * method:doSome args:doSome执行接受实参 proxy:代理监控对对象
						 **/
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							System.out.println("ISomeService doSome 被拦截");
							String result = (String) method.invoke(beanInstance, args);// beanInstance.doSome
							return result.toUpperCase();
						}

					});
			return proxy;
		}
		return beanInstance;
	}
	
	

}

 

4、beanFactory

 

 

   setValue模拟依赖注入:输入(实例对象、实例对象关联的类文件、propertyMap)

       循环遍历  propertyMap<属性名,属性值> 

       在类文件中寻找与属性名同名的方法 与对象

       Method methodArray[]= classFile.getDeclaredMethods();//类中所有方法

       找到属性对应的方法

       String methodName ="set"+fieldName; //拼接methodName

类似mybatis(spring)的类型转换器

       Class fieldType=   fieldObj.getType();//获取属性的数据类型 Integer,String,Double,boolean,list

       String value = (String) propertyMap.get(fieldName);//获取数值

   public Object invoke(Object obj,Object... args)
   参数:
   obj - 从中调用底层方法的对象
   args - 用于方法调用的参数 
   返回:
   使用参数 args 在 obj 上指派该对象所表示方法的结果 

   methodObj.invoke(instance, tempList);//参数为数组

       else{

          String dataArray[]=value.split(",");
          Object data[] = new Object[1]; //封装对象数组 
          data[0]=dataArray;
          methodObj.invoke(instance, data);  //需要对象数组 封装

       }

       break

 

 

getBean的时候setValue

public Object getBean(String beanId) 

getBean的时候注入

       

 


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BeanFactory {
	
	   private List<BeanDefined> beanDefinedList;
	   private Map<String ,Object> SpringIoc;//已经创建好实例对象
	   private BeanPostProcessor processorObj;//后置对象
	   

	public List<BeanDefined> getBeanDefinedList() {
		return beanDefinedList;
	}

	//依赖注入
	public void setValue(Object instance,Class classFile,Map propertyMap) throws NoSuchFieldException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		     //循环遍历  propertyMap<属性名,属性值> 
		     Method methodArray[]= classFile.getDeclaredMethods();
		     Set fieldNameSet = propertyMap.keySet();
		     Iterator fieldIterator = fieldNameSet.iterator();
		     while(fieldIterator.hasNext()){
		    	 String fieldName = (String) fieldIterator.next();
		    	 String value = (String) propertyMap.get(fieldName);
		    	 Field fieldObj = classFile.getDeclaredField(fieldName);//同名属性对象
                 
		    	 for(int i=0;i<methodArray.length;i++){
		    		 Method methodObj  = methodArray[i];
		    		 String methodName ="set"+fieldName;// sid == setsid
		    		 if(methodName.equalsIgnoreCase(methodObj.getName())){
		    			   Class fieldType=   fieldObj.getType();//属性的数据类型 Integer,String,Double,boolean,list
		    		       if(fieldType == String.class){
		    		    	   methodObj.invoke(instance, value);
		    		       }else if(fieldType == Integer.class){
		    		    	   methodObj.invoke(instance, Integer.valueOf(value));
		    		       }else if(fieldType == Boolean.class){
		    		    	   methodObj.invoke(instance, Boolean.valueOf(value));
		    		       }else if(fieldType==List.class){
		    		    	     List tempList = new ArrayList();
		    		    	     String dataArray[]=value.split(",");
		    		    	     for(int j=0;j<dataArray.length;j++){
		    		    	    	 tempList.add(dataArray[j]);
		    		    	     }
		    		    	     methodObj.invoke(instance, tempList);
		    		       }else{ //此时属性类型是数组
		    		    	   String dataArray[]=value.split(",");
		    		    	   Object data[] = new Object[1];
		    		    	   data[0]=dataArray;
		    		    	   methodObj.invoke(instance, data);
		    		       }
		    		          break;
		    		 }
		    	 }
		     }
	}
	
	public BeanFactory(List<BeanDefined> beanDefinedList) throws Exception {
		
		this.beanDefinedList = beanDefinedList;
		SpringIoc  = new HashMap(); //所有scope="singleton" 采用单类模式管理bean对象
		for(BeanDefined beanObj:this.beanDefinedList){
			if("singleton".equals(beanObj.getScope())){
				Class classFile= Class.forName(beanObj.getClassPath());
				Object instance= classFile.newInstance();
				//判断当前对象是一个bean对象还是后置处理处理对象
				isProcessor(instance,classFile);
				SpringIoc.put(beanObj.getBeanId(), instance);
			}
		}
		
	}
    private void isProcessor(Object instance,Class classFile){
    	         Class interfaceArray[] = classFile.getInterfaces();
    	         if(interfaceArray==null){
    	        	 return;
    	         }
    	         
    	         for(int i=0;i<interfaceArray.length;i++){
    	        	 Class interfaceType = interfaceArray[i];
    	        	 if(interfaceType == BeanPostProcessor.class){//证明当前实例对象是后置处理器
    	        		 this.processorObj = (BeanPostProcessor)instance;
    	        	 }
    	         }
    }



	public void setBeanDefinedList(List<BeanDefined> beanDefinedList) {
		this.beanDefinedList = beanDefinedList;
	}
	
	public Object getBean(String beanId) throws Exception{
		   Object instance = null;
		   Object proxyObj = null;//当前实例对象的代理监控对象
		   for(BeanDefined beanObj:beanDefinedList){
			     if(beanId.equals(beanObj.getBeanId())){
			    	 String classPath = beanObj.getClassPath();			    	 
					 Class classFile= Class.forName(classPath);
					 String scope=beanObj.getScope();
					 String factoryBean = beanObj.getFactoryBean();
					 String factoryMehtod=beanObj.getFactoryMethod();
					 Map propertyMap = beanObj.getPropertyMap();
					 if("prototype".equals(scope)){//.getBean每次都要返回一个全新实例对象
						  
						  if(factoryBean!=null && factoryMehtod!=null){//用户希望使用指定工厂创建实例对象
							       Object factoryObj=  SpringIoc.get(factoryBean);
							       Class factoryClass=factoryObj.getClass();
							       Method methodObj= factoryClass.getDeclaredMethod(factoryMehtod, null);
							       methodObj.setAccessible(true);
							       instance= methodObj.invoke(factoryObj, null);
						  }else{
							  instance= classFile.newInstance();
						  }
					 }else{
						 instance=SpringIoc.get(beanId);
					 }
					 
					 if(this.processorObj!=null){
						 proxyObj = this.processorObj.postProcessBeforeInitialization(instance, beanId);
						 //实例对象初始化。Spring依赖注入
						 setValue(instance,classFile,propertyMap);
						 proxyObj = this.processorObj.postProcessAfterInitialization(instance, beanId);
						 //此时返回proxyObj可能就是原始bean对象,也有可能就是代理对象
						 return proxyObj;
					 }else{
						 //实例对象初始化
						 setValue(instance,classFile,propertyMap);
						 return instance;
					 }
					 
					
			     }
		   }
		   return null;
	}
	   

}

 

5、test

public class TestMain {

	public static void main(String[] args) throws Exception {
		
		  //1.声明注册bean
		
		  
		  BeanDefined beanObj = new BeanDefined();
		  beanObj.setBeanId("teacher");
		  beanObj.setClassPath("com.myspring.beans.Teacher");
		  /*
		   *  <property>
		   * 
		   **/
		  Map<String, String> propertyMap =  beanObj.getPropertyMap();
		  propertyMap.put("teacherName", "李老师");
		  propertyMap.put("friendArray", "老刘,老孙,码畜");
		  propertyMap.put("school", "西南交大,西南联大");
		  
		  
		  List configuration = new ArrayList();
		  configuration.add(beanObj);//spring核心配置
		
		  
		  //2.声明一个Spring提供BeanFacotory
		  BeanFactory factory = new BeanFactory(configuration);
		 
		  
		  //3.开发人员向BeanFactory索要实例对象.
		  Teacher t= (Teacher) factory.getBean("teacher");
		  System.out.println("t="+t);
		  System.out.println(t.getTeacherName());
		 

	}

}

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值