spring3

课程主题
动态代理模式&Spring AOP源码阅读&原理分析
课程目标
1.要搞清楚jdk和cglib这两种动态代理模式创建代理对象的原理和代码
2.要搞清楚jdk和cglib这两种动态代理模式产生的代理对象被调用时的执行原理和代码
3.要搞清楚xml方式中aop标签底层是如何被解析及解析的结果是什么(十个BeanDefinition)
4.通过画图去说明上一步解析出来的十个BeanDefinition的作用。
5.搞清楚创建aop代理对象的入口在哪及相关的类是哪个?
6.搞清楚创建aop代理对象的流程
7.搞清楚aop代理对象的执行流程(拦截器链--MethodInterceptor\MethodInvocation)

课程回顾和课程内容
1.循环依赖
* 创建Bean的流程
** Bean的实例化
** Bean的属性填充
** Bean的初始化(非循环依赖场景下,如果要产生代理对象,在这个子流程中产生)

* Spring解决setter方法循环依赖的方式(三级缓存)
* 三级缓存的作用
* 三级缓存同一个时间段内,同一个beanName,只会存在于一个缓存中。
* 如果不是循环依赖的场景下,二级缓存和三级缓存是使用不到。
* 如何判断是否是处于循环依赖的场景下呢?
* 正在创建中的标识(Set集合)
* 一级缓存,存储的是最终的单例Bean(暴露给spring容器之外的客户端调用使用的)
* 二级缓存,存储的是正在创建中的单例Bean(暴露给spring框架内调用使用的)
* 三级缓存:存储的是ObjectFactory(工厂对象),该ObjectFactory是提前保存了正在创建中的Bean实例(new之后,set之前)
* ObjectFactory的作用:
* 保存提早暴露的单例Bean的引用
* 针对保存的Bean实例,通过BeanPostProcessor进行判断,看一看该Bean是否需要被功能增强,如果需要,则在此时针对该Bean产生代理对象
* 将产生的代理对象,放入二级缓存,同时删除该beanName对应的三级缓存数据
* 三级缓存的存放时间
* 第三级缓存:Bean实例化之后,属性填充之前,经过判断,将Bean实例封装到ObjectFactory,然后将ObjectFactory放入三级缓存
* 第二级缓存:当第一次从三级缓存中的ObjectFactory中获取被他保存的Bean实例,获取之后,就会放入二级缓存中
* 第一级缓存:当第一次完整的创建完Bean实例之后(三部曲之后),才会放入一级缓存,同时清楚二级和三级缓存。

* 三级缓存的获取顺序
* 一级缓存
* 二级缓存
* 三级缓存

2.aop核心概念的理解
通知
切入点
连接点
切面/通知器
目标对象
代理对象

3.动态代理模式(JDK动态代理模式)
* jdk动态代理模式(有接口的目标对象)
* 如何产生代理对象

Object proxy = Proxy.newProxyInstance(classloader,interfaces,InvocationHandler);
** 自己去想想我们只知道接口的情况下,如何写出实现类
* 产生代理对象的底层原理
* 由JDK编写代理类的源文件(.java)-----interfaces,InvocationHandler
* 有JDK编译成class文件
* 使用传入的classloader加载class文件---ClassLoader
* 如何执行代理对象

InvocationHandler.invoke(proxy , Method , args){
before();
//调用目标对象的目标方法
Method.invoke(target,args);
after();
}

* cglib动态代理模式(没有接口和非final的目标对象)---ASM(生成和修改字节码的工具包)
* 如何产生代理对象

Enhancer enhancer = new Enhancer();
enhancer.setSuperClass(目标对象的class对象);
enhancer.setCallback(MethodInterceptor的实现类);

Object proxy = enhancer.create();

* 产生代理对象的底层原理
* 使用ASM工具包去针对目标类的class文件,进行修改,产生新的class文件
* 如何执行代理对象

MethodInterceptor的实现类.intercept(proxy , targetMethod , args , proxyMethod){
before();
//调用目标对象的目标方法
//Method.invoke(target,args);
methodProxy.invokeSuper(proxy, arg);

after();

}
* 由InvocationHandler和MethodInterceptor产生的思考
** 如果invoke方法和intercept方法是我们程序员写好的,那怎么保证功能的扩展性呢?
** 通过配置去确定加哪些通知(前置、后置、最终)
** 通过一定的逻辑(执行链条---MethodInvocation和MethodInterceptor去完成)去控制多个通知的执行顺序。

** 多个前置通知的执行顺序如何保证?
** 一个前置通知和一个后置通知的执行顺序如何保证?

4.阅读spring aop源码
* spring中aop的用法有两种(spring aop方式【aop:advisor】、spring整合AspectJ的方式【aop:aspect】)
* <aop:advisor advice-ref="myAdvice"/>
* <aop:aspect ref="myAdvice">
* 获取十个BeanDefinition的流程(xml中的aop标签)
* 入口类和方法:BeanDefinitionParserDelegate#parseCustomElement


* 创建代理对象的流程
* 什么时候产生呢?
* AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
* 入口类和方法:AbstractAutoProxyCreator#postProcessAfterInitialization
* 代理对象执行流程(重要)

posted @ 2020-05-13 10:02  第二人生Bonnie  阅读(159)  评论(0编辑  收藏  举报