Spring源码分析总结

IOC

Application的继承关系

  1. ApplicationContext的实现类
    在这里插入图片描述
    图片来源于https://www.javadoop.com/post/spring-ioc

  2. ApplicationContext的父接口
    在这里插入图片描述图片来源于https://www.javadoop.com/post/spring-ioc

容器的启动过程

从AbstractApplicationContext抽象类的refresh方法开始。

  1. 准备工作
    记录下容器的启动时间,标记容器开启和关闭状态位,校验配置文件
  2. 解析配置文件,创建BeanDefinition实例,注册进BeanFactory中
    (1)将配置文件转换成一颗DOM树,从根节点开始解析文件。
    (2)解析default namespace涉及到的四个标签 < import/> < alias/> < bean/>和< beans/> ;
    解析其他属于custom下的标签
    (3)以< bean/>标签为例,根据标签下的内容形成一个个的BeanDefiniton,然后放入注册中心中,说到底核心是一个beanName->BeanDefinition的map
  3. 设置BeanFactory的类加载器,添加BeanPostProcessor,手动注册几个bean
  4. 具体的子类添加一个特殊的BeanFactoryPostProcessor 的实现类或做点什么事
  5. 调用上一步实现类的PostProcessorBeanFactory(factory)回调方法
  6. 注册BeanPostProcessor实现类,其中的两个方法会在Bean初始化之前和初始化之后得到执行
  7. 初始化当前ApplicationContext的MessageSource
  8. 初始化当前ApplicationContext的事件广播器
  9. 注册事件监听器
  10. 初始化所有的非懒加载 singleton beans
    (1)预初始化:如果有Bean继承关系,合并父Bean的配置;如果bean实现了SmartInitializingSingleton 接口,进行相应的函数回调等等。
    (2)正式初始化:判断bean是否已被初始化,若被初始化则直接返回,否则就进行初始化。分为三步:

第一步–创建Bean实例
如果不存在方法覆写,就利用java反射实例化,否则使用CGLB
第二步–Bean属性注入
通过名字装配、通过类型装配等
第三步–方法回调

  • 如果bean实现了BeanNameAware、BeanClassLoaderAware或者BeanFactoryAware接口,调用回调方法
  • 如果bean注册了BeanPostProcessor实现类,则调用postProcessBeforeInitialization 方法
  • 如果bean实现了initializingBean接口,调用afterProperties()方法
    调用init-method配置的方法
  • 如果bean注册了BeanPostProcessor实现类,则调用postProcessAfterInitialization 方法
  1. 广播事件

AOP

Spring对AOP的支持

Spring提供了四种类型的AOP支持,分别为:

  • 基于代理的经典SpringAOP
  • 纯POJO切面
  • @AspectJ注解驱动的切面
  • 注入式AspectJ切面(适用于Spring的各个版本)

前三种都是SpringAOP实现的变体,SpringAOP构建在动态代理基础上,因此Spring对AOP的支持局限于方法拦截。

基于xml配置的AOP模式

以DefaultAdvisorAutoProxyCreator 为例来进行追踪,可以发现它是BeanPostProcessor接口的子类。IOC容器在初始化Bean的最后一步中会调用回调方法postProcessAfterInitialization ,该方法是BeanPostProcessor的接口方法。
对于BeanPostProcessor的实现类AbstractAutoProxyCreator,它是这样实现postProcessAfterInitialization 方法的:

  1. 通过createProxy方法区创建ProxyFactory实例,ProxyFactory中包含了Advisor、targetSource等信息。其中的Advisor就是利用Pointcut正则表达式指定的范围匹配得来的。
  2. 使用createAopProxy方法返回AOPProxy实例。如果被代理的目标类实现了接口,就使用jdk动态代理;没有实现任何接口,会使用CGLIB实现代理;如果设置了proxy-target-class=“true”,那都会使用CGLIB。
    当类的方法被private或者final修饰的时候,也不能够使用jdk动态代理。
  3. 返回AopProxy实例后继续调用getProxy(classLoder)方法,因为AopProxy实例有jdk动态代理和CGLIB两种代理方法,所以会用两种不同的方式获得代理对象。
    在这里插入图片描述

基于注解驱动的AOP模式

Spring Aop中@Aspect的实现原理:
开启@Aspect有两种方式,一个是<aop:aspectj-autoproxy/>,一个是@EnableAspectJAutoProxy,它们的原理都是一样的,通过注册一个bean来实现。那这是一个怎样的Bean?

<aop:aspectj-autoproxy/>为例,解析这个标签会用到AopNamespaceHandler->AspectJAutoProxyBeanDefinitionParser-> …-> 注册了一个类名为AnnotationAwareAspectJAutoProxyCreator的Bean,查看继承关系,发现它也是BeanPostProcessor接口的一个实现类,所以后面同样会在IOC容器初始化Bean实例的最后调用回调方法创建Bean的代理对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值