人工智能

30个类手写Spring核心原理之依赖注入功能

时间:2010-12-5 17:23:32  作者:IT科技类资讯   来源:应用开发  查看:  评论:0
内容摘要:在之前的源码分析中我们已经了解到,依赖注入(DI)的入口是getBean()方法,前面的IoC手写部分基本流程已通。先在GPApplicationContext中定义好IoC容器,然后将GPBeanW

在之前的个类源码分析中我们已经了解到,依赖注入(DI)的手写入口是getBean()方法,前面的核心IoC手写部分基本流程已通。先在GPApplicationContext中定义好IoC容器,原理然后将GPBeanWrapper对象保存到Map中。赖注在GPApplicationContext中设计两个Map:factoryBeanObjectCache保存单例对象的入功缓存,factoryBeanInstanceCache保存GPBeanWrapper的个类缓存,变量命名也和原生Spring一致,手写这两个对象的核心设计其实就是云服务器注册式单例模式的经典应用。

public class GPApplicationContext extends GPDefaultListableBeanFactory implements GPBeanFactory {      private String [] configLocations;     private GPBeanDefinitionReader reader;     //用来保证注册式单例的原理容器     private Map<String,Object> factoryBeanObjectCache = new HashMap<String, Object>();     //用来存储所有的被代理过的对象     private Map<String,GPBeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<String, GPBeanWrapper>();     ... } 

1 从getBean()方法开始

下面我们从完善getBean()方法开始:

    @Override     public Object getBean(String beanName) {          GPBeanDefinition beanDefinition = super.beanDefinitionMap.get(beanName);         try{              //生成通知事件             GPBeanPostProcessor beanPostProcessor = new GPBeanPostProcessor();             Object instance = instantiateBean(beanDefinition);             if(null == instance){  return  null;}             //在实例初始化以前调用一次             beanPostProcessor.postProcessBeforeInitialization(instance,beanName);             GPBeanWrapper beanWrapper = new GPBeanWrapper(instance);             this.factoryBeanInstanceCache.put(beanName,beanWrapper);             //在实例初始化以后调用一次             beanPostProcessor.postProcessAfterInitialization(instance,beanName);             populateBean(beanName,instance);             //通过这样调用,相当于给我们自己留有了可操作的赖注空间             return this.factoryBeanInstanceCache.get(beanName).getWrappedInstance();         }catch (Exception e){  //            e.printStackTrace();             return null;         }     } 

2 instantiateBean()方法反射创建实例

//传一个BeanDefinition,就返回一个实例Bean private Object instantiateBean(GPBeanDefinition beanDefinition){      Object instance = null;     String className = beanDefinition.getBeanClassName();     try{          //因为根据Class才能确定一个类是入功否有实例         if(this.factoryBeanObjectCache.containsKey(className)){              instance = this.factoryBeanObjectCache.get(className);         }else{              Class<?> clazz = Class.forName(className);             instance = clazz.newInstance();             this.factoryBeanObjectCache.put(beanDefinition.getFactoryBeanName(),instance);         }         return instance;     }catch (Exception e){          e.printStackTrace();     }     return null; } 

3 populateBean()方法完成依赖注入

    private void populateBean(String beanName,Object instance){          Class clazz = instance.getClass();         if(!(clazz.isAnnotationPresent(GPController.class) ||                 clazz.isAnnotationPresent(GPService.class))){              return;         }         Field [] fields = clazz.getDeclaredFields();         for (Field field : fields) {              if (!field.isAnnotationPresent(GPAutowired.class)){  continue; }             GPAutowired autowired = field.getAnnotation(GPAutowired.class);             String autowiredBeanName = autowired.value().trim();             if("".equals(autowiredBeanName)){                  autowiredBeanName = field.getType().getName();             }             field.setAccessible(true);             try {                  field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName). getWrappedInstance());             } catch (IllegalAccessException e) {  //                e.printStackTrace();             }         }     } 

4 GPBeanPostProcessor后置处理器

原生Spring中的BeanPostProcessor是为对象初始化事件设置的一种回调机制。这个Mini版本中只做说明,个类不做具体实现,服务器托管手写感兴趣的核心“小伙伴”可以继续深入研究Spring源码。

package com.tom.spring.formework.beans.config; public class GPBeanPostProcessor {      //为在Bean的初始化之前提供回调入口     public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {          return bean;     }     //为在Bean的初始化之后提供回调入口     public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {          return bean;     } } 

至此,DI部分就手写完成了,也就是说完成了Spring的核心部分。“小伙伴们”是不是发现其实还是很简单的?

copyright © 2025 powered by 益强资讯全景  滇ICP备2023006006号-31sitemap