学习写简单Spring源码demo
最近在研究怎么实现简单的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的更多相关文章
- Sping学习笔记(一)----Spring源码阅读环境的搭建
idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...
- mybatis源码学习(二)--mybatis+spring源码学习
这篇笔记主要来就,mybatis是如何利用spring的扩展点来实现和spring的整合 1.mybatis和spring整合之后,我们就不需要使用sqlSession.selectOne()这种方式 ...
- springMvc源码学习之:spring源码总结
转载自:http://www.cnblogs.com/davidwang456/p/4213652.html spring beans下面有如下源文件包: org.springframework.be ...
- 学习写简单的RPC框架demo
学习实现一个简单的RPC框架. 工程主要目录分级结构: rpc-common: 公共基础包,能力提供包 rpc-provider: 服务提供者 rpc-consumer:服务消费者 rpc-servi ...
- Spring源码学习01:IntelliJ IDEA2019.3编译Spring5.3.x源码
目录 Spring源码学习01:IntelliJ IDEA2019.3编译Spring5.3.x源码 前言 工欲善其事必先利其器.学习和深读Spring源码一个重要的前提:编译源码到我们的本地环境.这 ...
- Spring源码学习
Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...
- Spring源码分析 之浅谈设计模式
一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级 零配置, ...
- Spring源码解析 | 第一篇 :IntelliJ IDEA2019.3编译Spring5.3.x源码
前言 工欲善其事必先利其器.学习和深读Spring源码一个重要的前提:编译源码到我们的本地环境.这样方便我们在本地环境添加注释.断点追踪.查看类或接口的继承关系等等,更加高效的学习Spring源码.个 ...
- [spring源码] 小白级别的源码解析(一)
一直都在用spring,但是每次一遇到spring深入的问题,就是比较懵的状态.最近花了段时间学习了一下spring源码. 1,spring版本介绍 虽然工作中,一直在用到spring,可能有时候,并 ...
随机推荐
- 数据结构 - 堆(Heap)
数据结构 - 堆(Heap) 1.堆的定义 堆的形式满足完全二叉树的定义: 若 i < ceil(n/2) ,则节点i为分支节点,否则为叶子节点 叶子节点只可能在最大的两层出现,而最大层次上的叶 ...
- spring怎么避免循环依赖
1.循环依赖 (1)概念 对象依赖分为强依赖和弱依赖: 强依赖指的是一个对象包含了另外一个对象的引用,例如:学生类中包含了课程类,在学生类中存在课程类的引用 创建课程类: @Data public c ...
- java经典算法40题-附带解决代码
前一段时间工作比较闲,每天没有代码敲的日子有点无聊,于是为了保证自己的编程逻辑力的日常清醒,故百度了一些经典的java算法,然后自己思考编程解决问题,虽然那些东西比较基础了,但是有些题目小编看到了也是 ...
- Java基础——锁
1.锁 当一个共享资源被多方访问时为了避免发生冲突而施加的一种机制 2.乐观锁和悲观锁 Java中锁在宏观分为乐观锁和悲观锁 乐观锁:是一种乐观思想,认为多读少写,一般情况下数据在修改时不会出现冲突, ...
- 制作u盘启动盘
制作u盘启动盘 如果是想要制作 windows 系统启动盘,windows 官网提供途径,这里不在赘述. 以下讨论制作 centos 系统启动盘,需要 centos 系统文件,开源,可从官网下载得到. ...
- 044 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 06 使用do-while循环实现猜字游戏
044 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 06 使用do-while循环实现猜字游戏 本文知识点:do-while循环深入运用 案例练习 案例 ...
- matlab find函数使用语法
find 找到非零元素的索引和值 语法: 1. ind = find(X) 2. ind = find(X, k) 3. ind = find(X, k, 'first') 4. ind = find ...
- 《凤凰项目:一个IT运维的传奇故事》读书笔记
- 手把手教你安装TensorFlow2 GPU 版本
参考博客:https://blog.csdn.net/weixin_44170512/article/details/103990592 (本文中部分内容引自参考博客,请大家支持原作者!) 感谢大佬的 ...
- mycat 全局表
全局表的作用 在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具有以下几个特性: 变动不频繁 数据量总体变化不大 数据规模不大,很 ...