单手写Spring系列 (5) DI

 

原始框架赋值

单手写Spring系列 (5) DI_第1张图片

 

 

模拟依赖注入

1、实体

属性待注入


public class Teacher {
	  
    private  String teacherName;
    private  String friendArray[];
    private  List   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 getSchool() {
		return school;
	}
	public void setSchool(List school) {
		this.school = school;
	}
    
    
   
}

增加map存放属性

2、beandefine

注入:propertyMap


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

public class BeanDefined {
	/*
	 * 
	 *   
	 *   
	 **/
	private String beanId;
	private String classPath;
	private String scope ="singleton";
	private String factoryBean=null;
	private String factoryMethod=null;
	private Map propertyMap=new HashMap();
	
	
	public Map getPropertyMap() {
		return propertyMap;
	}
	public void setPropertyMap(Map 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的时候注入

单手写Spring系列 (5) DI_第2张图片

       

 


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 beanDefinedList;
	   private Map SpringIoc;//已经创建好实例对象
	   private BeanPostProcessor processorObj;//后置对象
	   

	public List 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 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 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");
		  /*
		   *  
		   * 
		   **/
		  Map 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());
		 

	}

}

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Spring)