最近在研究怎么实现简单的Spring的源码,通过注解的方式来实现对bean的加载管理。

首先先来看下我的工程结构:

(1)spring-common:定义了常用的枚举常量,工具类(如FileUtils提供了递归找到某个目录下所有文件的具体实现)

(2)spring-frame:是整个框架的具体实现,依赖spring-common

(3)spring-test:提供了一个简单的测试demo

我们先看测试类,这个应该更熟悉,简单得到bean实例的代码:

public static void main(String[] args) {

        // 1. 启动Spring
MyApplicationContext context = new MyApplicationContext(AppConfig.class);
// 2. getBean
OrderService orderService = (OrderService) context.getBean("orderService");
orderService.getUserInfo(); }

其中我们引用了自己定义的MyApplicationContext来启动Spring去装载bean,并对bean进行初始化和实例化。

针对MyApplicationContext, 核心构造方法:

public MyApplicationContext(Class configClass) {
// Spring启动要做什么事情?
// 扫描类 --> 创建非懒加载的单例的bean --> 放入单例池
// 1. 单纯扫描包
List<Class> classList = scanSpecifiedPath(configClass);
// 2. 解析出文件中的bean
initialBeanDefinition(classList);
// 3. 实例化单例的bean
instantiateSingletonBean();
}

再上述看到的三个方法中,主要是使用了我们自己定义的@ComponentScan, @Component, @Scope, @Autowired注解来实现bean的扫描,识别,是否单例,依赖注入;

针对bean的初始化和后置处理,我们定义了同Spring原生的接口:InitializingBean,BeanPostProcessor来实现。

其中,我们特意构造了getBean的方法,核心代码如下:

public Object getBean(String beanName) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (Objects.equals(beanDefinition.getScope(), BaseConstant.Scope.PROTOTYPE)) {
// 重新创建
return doCreateBean(beanName, beanDefinition);
} else if (Objects.equals(beanDefinition.getScope(), BaseConstant.Scope.SINGLETON)) {
Object obj = singletonObjectPool.get(beanName);
if (Objects.isNull(obj)) {
// 创建单例bean
obj = doCreateBean(beanName, beanDefinition);
singletonObjectPool.put(beanName, obj);
}
return obj;
}
return null;
}

可以简单看到,针对Scope为原型的bean,直接创建了一个bean的实例;单例模式的bean会先从单例池中直接获取,否则才会创建之后再加入单例池。

简单描述到这里,更多实现细节和demo测试,见gitee源码:

 https://gitee.com/leijisong/myspring-demo

学习写简单Spring源码demo的更多相关文章

  1. Sping学习笔记(一)----Spring源码阅读环境的搭建

    idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...

  2. mybatis源码学习(二)--mybatis+spring源码学习

    这篇笔记主要来就,mybatis是如何利用spring的扩展点来实现和spring的整合 1.mybatis和spring整合之后,我们就不需要使用sqlSession.selectOne()这种方式 ...

  3. springMvc源码学习之:spring源码总结

    转载自:http://www.cnblogs.com/davidwang456/p/4213652.html spring beans下面有如下源文件包: org.springframework.be ...

  4. 学习写简单的RPC框架demo

    学习实现一个简单的RPC框架. 工程主要目录分级结构: rpc-common: 公共基础包,能力提供包 rpc-provider: 服务提供者 rpc-consumer:服务消费者 rpc-servi ...

  5. Spring源码学习01:IntelliJ IDEA2019.3编译Spring5.3.x源码

    目录 Spring源码学习01:IntelliJ IDEA2019.3编译Spring5.3.x源码 前言 工欲善其事必先利其器.学习和深读Spring源码一个重要的前提:编译源码到我们的本地环境.这 ...

  6. Spring源码学习

    Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...

  7. Spring源码分析 之浅谈设计模式

    一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级  零配置, ...

  8. Spring源码解析 | 第一篇 :IntelliJ IDEA2019.3编译Spring5.3.x源码

    前言 工欲善其事必先利其器.学习和深读Spring源码一个重要的前提:编译源码到我们的本地环境.这样方便我们在本地环境添加注释.断点追踪.查看类或接口的继承关系等等,更加高效的学习Spring源码.个 ...

  9. [spring源码] 小白级别的源码解析(一)

    一直都在用spring,但是每次一遇到spring深入的问题,就是比较懵的状态.最近花了段时间学习了一下spring源码. 1,spring版本介绍 虽然工作中,一直在用到spring,可能有时候,并 ...

随机推荐

  1. burp suite 之 Scanner(漏洞扫描)

    Scanner选项:是一个进行自动发现 web 应用程序的安全漏洞的工具. 将抓取的包 通过选项卡发送至 Scanner下的Scan queue 首先来介绍 Scanner 下的 lssue acti ...

  2. Android Handler 分析学习

    一.Handler简介 Handler 是 Android 中用于线程间交互的机制.与其相关的概念有 Thread.Looper.Runnable.Message.MessageQueue 等. Go ...

  3. Windows控件的属性与事件

    Treeview控件重要属性和事件 属性 说明 Nodes Treeview控件中所有树节点 SelectdNode 当前Treeview控件中选定的树节点,如果当前没有选定树节点,返回值为null ...

  4. 放弃"指针常量"这种不严谨的中文描述!深度理解数组名、指针常量

    ques1: 数组名完全等价于指针常量吗? int array[10] = { 10,11,12,13,14,15 }; printf("sizeof(array)= %d \n" ...

  5. 日志分析平台ELK之日志收集器filebeat

    前面我们了解了elk集群中的logstash的用法,使用logstash处理日志挺好的,但是有一个缺陷,就是太慢了:当然logstash慢的原因是它依赖jruby虚拟机,jruby虚拟机就是用java ...

  6. 开发基于Django和Websocket的堡垒机

    WebSSH有很多,基于Django的Web服务也有很多,使用Paramiko在Python中进行SSH访问的就更多了.但是通过gevent将三者结合起来,实现通过浏览器访问的堡垒机就很少见了.本文将 ...

  7. matlab中set设置图形属性

    来源:https://ww2.mathworks.cn/help/matlab/ref/set.html?searchHighlight=set&s_tid=doc_srchtitle set ...

  8. python框架day01

    一.注意事项 # 如何让你的计算机能够正常的启动django项目 1.计算机的名称不能有中文 2.一个pycharm窗口只开一个项目 3.项目里面所有的文件也尽量不要出现中文 4.python解释器尽 ...

  9. lua 1.0 源码分析 -- 总结

    读完 lua1.0 的源码感触:1. 把复杂的代码写简单2. pack 的内存回收3. hash 实现简单,但是应该可以改进,看高版本的代码怎么实现4. lua 初始化环境做了什么,就是一组全局变量初 ...

  10. GUI版本的emacs

    概要 emacs 配置 X11 配置 输入法配置 spacemacs 中的配置 fcitx 汉字显示方块的问题 总结 优势 劣势 概要 之前一直使用 terminal 版本的 emacs, 性能和显示 ...