Spring源码基础解析

Spring从哪开始?

  • 聊聊spring
  • 说明bean的生命周期
  • 循环依赖
  • 三级缓存
  • FactoryBean和beanFactory
  • ApplicationContext和BeanFactory的区别
  • 设计模式

什么是Spring?
总 :spring认知
Spring是一个基础的框架(轻量级框架),同时给我们提供了bean的容器,用来帮助我们方便装载具体的bean对象,我们之前在使用对象的时候,必须要程序员自己创建,而现在我们只需要告诉容器有哪些对象,他会帮我们创建好,并且维护整个整体的生命周期,我们在Spring的技术之上还有SpringBoot、SpringCloud一系列扩展的技术框架,这个框架都是在Spring框架为基石的,在上面进行一些扩展开发。
分 ioc
Spring框架中有两个非常重要的特性 IOC 、AOP
IOC表示的是控制反转,原来是我们程序员自己创建对象,现在都交给Spring框架的IOC容器进行创建,管理Bean对象。
AOP表示面向切面编程, 一些用于更业务逻辑无关的代码我们可以通过AOP的方式进行实现,我们日常使用中日志、权限控制,统一上传> 文件参数校验等等都是通过AOP进行实现, 具体的业务逻辑该怎么写就怎么写,后面需要进行扩展的时候可以通过AOP里面的通知往具体
方法的前置、后置、中间、环绕等不同的环境里面添加具体的更业务无关的代码,完成我们具体的功能

Spring在一般情况下都分为两个部分

  1. IOC :控制反转,由Spring进行创建对象,实现层解耦
  2. AOP :面向切面变成,将工程代码与工具代码分离,实现主次解耦

谈到Spring,就一定会说到Spring容器也就是Ioc容器
IOC容器 : 承载某些或者具体的事务(Bean对象)

bean
数据结构
map
三级缓存
K-V格式的数据
创建对象
获取对象
Bean的实例对象

在这里插入图片描述
在这里插入图片描述

Spring的基本运行

在这里插入图片描述
Spring是如何进行创建对象的呢?

  1. 首先提前定义好我们需要的bean对象的描述信息(也就是我们application.xml配置好的文件)
  2. xml对于spring来说,类似于定义的读取文件的配置规范 (这里xml就是定义的规范)
  3. spring通过定义的xml文件规范格式拿到对应的bean定义信息BeanDefinition
  4. 解析这些信息,通过反射的方式实例化bean对象
  5. 然后初始化bean对象,得到一个完整的bean对象

接口 自上向下 不考虑子类实现,遵循接口规范,自上向下
抽象类 自下向上 【三个类有共同特点】生成抽象类,考虑子类之间共性, 自下向上

  • BeanDefinition
    上述Spring的基本运行中,你所有的定义描述信息都在XML文件里面,如何读取呢?
    当然通过 new ClassPathXmlApplicationContext(“applicationcontext.xml”)
    该代码就是读取XML文件,而Bean对象信息就在xml里面,Bean的定义信息通过XML读取到了IOC容器中,此时,IOC的容器出现了bean的定义信息,并赋予了一个名字:BeanDefinition
  • BeanDefinitionReader
    BeanDefinitionReader :规范信息的接口
    BeanDefinitionReader 的作用是读取 Spring 配置文件中的内容,将其转换为 IoC 容器内部的数据结构:BeanDefinition
  • 反射
    • 获取Class对象
      • Class clazz = Class.forName(“完全限定名”);
      • Class clazz = 对象.getClass();
      • Class clazz = 类型.Class;
    • 获取构造器
      • Constructor ctor = clazz.getDeclaredConstructor();
    • 获取对象
      • Object obj = ctor.newInstance();

注意点 :实例化与初始化的区别

实例化
再堆中开辟一块空间属性值都是默认值
初始化
给属性完成赋值操作
填充属性
调用初始化方法
  • 增强器

为了Spring扩展实现

PostProcessor
增强器
后置处理器
扩展

例如下面加载数据库链接,${}内的变量是如何替换的呢?这里就用到了扩展
在这里插入图片描述

    <!--配置数据库连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClassName" value="${jdbc.driverClass}"/>
    </bean>

BeanFactoryPostProcessor与BeanPostProcessor的区别

BeanFactoryPostProcessor用来处理bean的定义信息BeanDefinition
BeanPostProcessor用来处理Bean对象(包含实例化与初始化)

BeanFactoryPostProcessor用来处理bean的定义信息BeanDefinition

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在占位符还存在
在这里插入图片描述
调用invokeBeanFactoryPostProcessors 占位符已经替换了
在这里插入图片描述
在这里插入图片描述
自己扩展,实现BeanFactoryPostProcessor,在创建对象前修改bean的定义信息BeanDefinition
在这里插入图片描述

BeanPostProcessor用来处理Bean对象(包含实例化与初始化)

在这里插入图片描述
在这里插入图片描述
实现AOP,需要用到动态代理

  • 动态代理
    • ObjenesisCglibAopProxy
    • JdkDynamicAopProxy
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

postProcessAfterInitialization方法会执行wrapIfNecessary,最终会执行到createAopProxy方法

    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }
  
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
    
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

在这里插入图片描述

Environment

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扩展 SpringBoot
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值