您现在的位置是:亿华云 > IT科技类资讯
30个类手写Spring核心原理之依赖注入功能
亿华云2025-10-09 15:14:59【IT科技类资讯】1人已围观
简介在之前的源码分析中我们已经了解到,依赖注入(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的核心部分。“小伙伴们”是不是发现其实还是很简单的?
很赞哦!(71)
相关文章
- 2、根据用户基础选择访问提供程序。由于互联问题的存在,接入商的选择也非常重要,如果用户群主要在联通,尽量选择联通接入较好的接入商,如果用户群主要在电信,那么选择电信接入较好的接入商。如果用户组位于国家/地区,则选择更好的访问提供程序进行交互。
- date域名可以做网站吗?date的网站后缀未来会如何?
- cn域名怎么玩的?个人注册cn域名有什么要求?
- 想要注册域名有哪些流程?新手流程要知道什么?
- 5. 四种状态过后,域名管理机构释放域名给公众注册。
- 新手对域名建站是如何理解的?该怎么进行建站?
- 域名与商标冲突吗?新手要掌握哪些区别?
- 新手在域名挑选时需要考量什么?如何做?
- 为什么现在中文域名觉得好?使用中文域名有什么好处?
- 如何区别好域名与坏域名?有什么细节可分清?
站长推荐
3、不明先知,根据相关征兆预测可能发生的事件,以便提前做好准备,赶紧注册相关域名。;不差钱域名;buchaqian抢先注册,就是这种敏感类型。预言是最敏感的状态。其次,你应该有眼力。所谓眼力,就是善于从社会上时不时出现的各种热点事件中获取与事件相关的域名资源。眼力的前提是对域名领域的熟悉和丰富的知识。
域名转出与过户什么联系?有什么需要了解的?
域名为何成为“拦路虎”?域名常见的几大经典问题须知
域名投资为什么做好这些准备是必要的?投资域名注意什么?
打开https://www.aizhan.com/输入自己想要查询的域名然后按回车键,如果做过网站都会有数据显示出来
新手想要进行域名交易怎么办?有没有好的去处?
为什么锤子科技要以smartisan.love为域名?love域名有什么梗?
建站有哪些需要的?怎么才能选一个好的建站域名?