最近在研究怎么实现简单的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. HTML你好!

    初识HTML 什么是HTML web的本意是蜘蛛网和网的意思,在网页设计中我们称为网页的意思.现广泛译作网络.互联网等技术领域.表现为三种形式,即超文本(hypertext).超媒体(hypermed ...

  2. Linux MMC 驱动子系统简述(源码剖析)

    1. Linux MMC 驱动子系统 块设备是Linux系统中的基础外设之一,而 MMC/SD 存储设备是一种典型的块设备.Linux内核设计了 MMC子系统,用于管理 MMC/SD 设备. MMC ...

  3. Leetcode-dfs & bfs

    102. 二叉树的层次遍历 https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ 给定一个二叉树,返回其按层次遍历的节 ...

  4. Python练习题 041:Project Euler 013:求和、取前10位数值

    本题来自 Project Euler 第13题:https://projecteuler.net/problem=13 # Project Euler: Problem 13: Large sum # ...

  5. 零基础小白必看篇:从0到1构建Python Web框架

    造轮子是最好的一种学习方式,本文尝试从0开始造个Python Web框架的轮子,我称它为ToyWebF. 本文操作环境为:MacOS,文中涉及的命令,请根据自己的系统进行替换. ToyWebF的简单特 ...

  6. Layman 解决MUI 软键盘弹起挤压页面问题

    问题:在使用mui和H5+进行移动端开发的时候,经常会遇见需要用户输入的情况 当input获取焦点弹起软键盘的时候,经常会遇见软键盘挤压页面.软键盘遮挡输入框等一系列问题: 原因:造成这种现象的原因是 ...

  7. 042 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 04 案例演示while循环的使用——循环输出英文字母

    042 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 04 案例演示while循环的使用--循环输出英文字母 本文知识点:案例演示while循环的使用2 ...

  8. Visual C++中各种文件的作用(详细)

    参考:http://blog.sina.com.cn/s/blog_6975d67c0100r3kx.html DSW:全称是Developer Studio Workspace,最高级别的配置文件, ...

  9. NOIP提高组2016 D2T3 【愤怒的小鸟】

    貌似还没有写过状压DP的题目,嗯,刚好今天考了,就拿出来写一写吧. 题目大意: 额,比较懒,这次就不写了... 思路分析: 先教大家一种判断题目是不是状压DP的方法吧. 很简单,那就是--看数据范围! ...

  10. jq显示数据在kindeditor

    1,定义编辑器的变量为全局变量 2,将数据显示到kindeditor   在我自己这里_下划线相当于数据,也就是将数据显示在kindeditor 中的textarea中 3,jquery获取kinde ...