Spring 源码概述

Spring 源码概述

Spring源码相关的面试题

  1. 谈一下spring IOC的底层实现?
  2. Spring的AOP的底层实现原理?

Spring设计架构推导

一个简单的sprin例子

  1. 创建bean类
    public class Student {
        private int id;
        private String name;
        private static String gender = "男";
        // 省略getter/setter
    }	
    
  2. Spring配置文件中定义bean信息
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean class="com.xxx.Student" id="student">
            <property name="id" value="1"></property>
            <property name="name" value="zhangsan"></property>
        </bean>
    </beans>	
    
  3. 加载配置文件

    xml配置文件,可通过ClassPathXmlApplicationContext加载

      public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("my-test.xml");
        }
    
  4. 从IOC容器获取bean进行使用
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("my-test.xml");
            Student student = context.getBean(Student.class);
            System.out.println("姓名 " + student.getName());
        }
    

架构推导过程

首先,我们知道spring的2大核心是IoCAOP,那么架构设计上怎么实现的呢?先建立一个框架的共识:**保证高内聚、低耦合、扩展性!**下面我们将根据上面的简单例子,推导一下整体的架构设计和引出一部分的专业名词。

image-20210526091130754

配置信息的加载

bean信息有可能是通过xml配置文件定义,也有可能是通过注解定义,甚至property文件定义等等。因此,为了屏蔽不同的bean信息定义实现的不同细节,需要抽出一个公共的读取配置信息的接口BeanDefinitionReader接口。加载了bean的定义信息,假设直观地我们将它存放在Map中,然后交给别的工厂类去使用。

bean生产工厂

假设有个BeanFactory,是专门负责拿到配置信息后生产出来bean的。在生产之前,我们想要个性化定制一下这个工厂,个性化地修改一下拿到的bean定义信息,这里就有扩展性的要求,设计框架的就需要提供扩展接口,这里提供一个BeanFactoryPostProcessor接口,可以扩展地修改bean生产工厂的东西。

bean的实例化

BeanFactory拿到了bean的定义信息。如何实例化bean?用反射,obj=class.getConstructor().newInstance()

// bean的定义信息  
<bean class="com.xxx.Student" id="student">
        <property name="id" value="1"></property>
        <property name="name" value="zhangsan"></property>
    </bean>
// 反射的实例化代码
    obj=class.getConstructor().newInstance() 
bean的初始化

bean通过反射实例化后,需要进行初始化,也就是设置属性值。那么扩展需求来了,我们想个性化处理一下实例化后的bean,框架给开个口子呗。于是得提供扩展接口BeanPostProccesor接口。这里提前埋个点,我们常常使用的aop就是在BeanPostProccesor中实现的,这个后续再详细讲。

bean的初始化完成后,我们直接存放到Map中,提供给程序调用,spring中的基本IOC功能就有了。

监听器

作为一个框架,如果别人提需求说,在上面的各个过程或是阶段中,例如bean生产工厂准备好了,bean的初始化都完成了,我们想知道,想干点别的事情,怎么办?那么就需要监听器,采用观察者模式,发生上面各个阶段事情后,通知发布出去。

环境

上面这些过程,有些地方需要用到系统当前用户、系统环境变量信息等,那么就需要有地方事先准备并存放起来,就有了Environment

总结

上面我们粗略地推导了spring的架构设计。在这个基础上,我们自己也可以实现一个简单的IoC容器功能,大体思路是:读取bean的配置信息,通过反射实例化和初始化,存放到Map中给外部程序调用,感兴趣的可以自行动手实践下。

后续我们的源码阅读,将按照先总后分,先整体脉络后部分细节的方式进行。

Spring源码预览

回顾一下上面的推导,我们实现IOC的过程如下:

image-20210526100411904

在这里我们先总结给出Spring源码的图,后续将深入各个部分进行源码阅读。

spring源码预览.png

源码设计到的关键接口列表

序号接口名
1BeanFactory
2Aware
3BeanDefinition
4BeanDefinitionReader
5BeanFactoryPostProcessor
6BeanPostProcessor
7Environment/StandardEnviroment

知识分享,转载请注明出处。学无先后,达者为先!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值