学习写简单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

posted @ 2020-09-06 11:32  未知的九月  阅读(396)  评论(0编辑  收藏  举报