Spring源码分析笔记--AOP
核心类&方法
BeanDefinition


Bean的定义信息,封装bean的基本信息,从中可以获取类名、是否是单例、是否被注入到其他bean中、是否懒加载、bean依赖的bean的名称等。
Aware

继承Aware的bean可以感知到他在容器中的一些属性,如获取bean在容器中的ID,甚至获取到容器等。
BeanPostProcessor

Bean的后置处理器,可在bean的创建、初始化等阶段的前后对bean进行增强处理等。
BeanFactory


以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
是访问容器的顶层接口,他的实现类中会有一个MAP,用于存储bean的BeanDefinition。
(与FactoryBean区别:实现FactoryBean接口也是在容器中注入bean的方式之一,但它不是一个普通的bean,而是生成指定bean的一个工厂)
AbstractAutowireCapableBeanFactory:: populateBean(..)
DefaultListableBeanFactory继承了AbstractAutowireCapableBeanFactory
此方法用于给bean注入依赖的其他bean
BeanWrapper
将交于容器管理的bean装饰,屏蔽多样性,统一的set、get方法,方便统一操作
核心流程源码
AnnotationAwareAspectJAutoProxyCreator创建过程
AOP核心类:AnnotationAwareAspectJAutoProxyCreator,本质是一种BeanPostProcessor
容器启动时:
==》 org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)
register(annotatedClasses);//加载、注册配置类;配置类也是一个被容器管理的bean
refresh();//刷新容器,注册、创建相关bean
==》 org.springframework.context.support.AbstractApplicationContext#refresh
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);//注册容器需要的核心BeanPostProcessor
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//创建并初始化其他非懒加载的bean,主要是业务类bean
==》 org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
==》 org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
// Separate between BeanPostProcessors that implement PriorityOrdered, Ordered, and the rest.
//根据继承的order等级,顺序创建BeanPostProcessor
//AnnotationAwareAspectJAutoProxyCreator实现了Order
//创建
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//添加到容器-FactoryBean中
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanPostProcessor>)
==》 org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class<T>)
==》 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean//BeanPostProcessor和业务Bean都用此创建bean
//创建bean
return createBean(beanName, mbd, args);
==》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//有一次通过代理直接返回对象的机会,但一般都不会走到此方法中
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//创建过程
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
==》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
//创建Bean,通过Wrapper装饰
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
//填充bean后初始化bean
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
==》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
//初始化bean
//检查实现了哪些aware,并注入相应的值
invokeAwareMethods(beanName, bean);
//BeanPostProcessor初始化前置处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用bean的初始方法
invokeInitMethods(beanName, wrappedBean, mbd);
//BeanPostProcessor初始化后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
==》 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
//此类做Bean初始化的后置处理,若bean有advice则创建proxy bean,此bean无。
业务Bean(proxy)创建过程
容器启动时:
==》 org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)
register(annotatedClasses);//加载、注册配置类;配置类也是一个被容器管理的bean
refresh();//刷新容器,注册、创建相关bean
==》 org.springframework.context.support.AbstractApplicationContext#refresh
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);//注册容器需要的核心BeanPostProcessor
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//创建并初始化其他非懒加载的bean,主要是业务类bean
==》 org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
==》 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
//getBean(beanName);
==》 org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
==》 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
return createBean(beanName, mbd, args);
==》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
//创建Bean,通过Wrapper装饰
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
//填充bean后初始化bean
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
==》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
//初始化bean
//检查实现了哪些aware,并注入相应的值
invokeAwareMethods(beanName, bean);
//BeanPostProcessor初始化前置处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用bean的初始方法
invokeInitMethods(beanName, wrappedBean, mbd);
//BeanPostProcessor初始化后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
==》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
//此类做Bean初始化的后置处理,若bean有advice则创建proxy bean
//遍历bean的后置处理器,并做后置处理
//当后置处理器时AnnotationAwareAspectJAutoProxyCreator时进入方法,判断是否需要做代理
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
==》 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
==》 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
==》 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
//bean需要被aop做代理进行增强时进入此方法
//取得bean对应的advisors,advisors会被封装成链式Interceptors(责任链模式)供后期增强使用
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//使用代理工厂创建代理
return proxyFactory.getProxy(getProxyClassLoader());
==》 org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
return createAopProxy().getProxy(classLoader);
==》 org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy
return getAopProxyFactory().createAopProxy(this);
==》 org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
//如果继承自接口使用JDK动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//否则使用CGLib动态代理
return new ObjenesisCglibAopProxy(config);
Bean的创建梳理
包括工具Bean、业务Bean
1、bean在缓存中(Map)是否存在,存在则直接返回,不存在进入创建流程
2、创建BeanPostProcessor后置处理器
是否实现Aware,实现则注入对应容器信息
3、创建自身bean
创建àpopulateBeanàInvoke InitMethod(若有advice此时创建proxy)
AOP advice过程
在业务方法中加断点,调试进入

==》 org.springframework.aop.framework.JdkDynamicAopProxy#invoke
//当被代理类实现了接口时使用jdk动态代理
// Get the interception chain for this method.
//获取通知封装成的链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
//容器在封装advisors成Interceptors时会进行排序,此顺序和实际执行顺序相反,因为Interceptors会以责任链的形式调用,因此实际执行时顺序是正常的
retVal = invocation.proceed();
AOP 方法增强梳理
1、创建AOP核心类:AnnotationAwareAspectJAutoProxyCreator
2、在注入时,CreateBean时,检查是否有Advice,如果有则创建bean的代理。
注意:代理类对象(proxy)会加入容器,但Context::BeanFactory::BeanDefinition中的定义信息仍是被代理类的,所以取到的name也是被代理类的。
代理类会在被代理类调用populateBean 、InitMethod后创建,
3、被增强的方法在调用时,会调用代理类的方法,方法中获取相应通知做增强处理。这些通知会被封装成MethodInterceptor,对切点进行拦截增强处理。
Spring源码分析笔记--AOP的更多相关文章
- Spring源码分析之AOP从解析到调用
正文: 在上一篇,我们对IOC核心部分流程已经分析完毕,相信小伙伴们有所收获,从这一篇开始,我们将会踏上新的旅程,即Spring的另一核心:AOP! 首先,为了让大家能更有效的理解AOP,先带大家过一 ...
- spring源码分析(二)Aop
创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...
- 【Spring源码分析】AOP源码解析(上篇)
前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...
- Spring源码分析之AOP
1.AOP简介 AOP即面向切面编程(Aspect Oriented Programming),通过预编译方式及运行期动态代理实现程序功能的统一维护的一种技术.使用aop对业务逻辑的各个部分进行隔离, ...
- 【Spring源码分析】AOP源码解析(下篇)
AspectJAwareAdvisorAutoProxyCreator及为Bean生成代理时机分析 上篇文章说了,org.springframework.aop.aspectj.autoproxy.A ...
- Spring源码分析笔记--事务管理
核心类 InfrastructureAdvisorAutoProxyCreator 本质是一个后置处理器,和AOP的后置处理器类似,但比AOP的使用级别低.当开启AOP代理模式后,优先使用AOP的后置 ...
- Spring源码分析之`BeanFactoryPostProcessor`调用过程
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 本文内容: AbstractApplicationContext#refresh前部分的一点小内容 ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- Spring源码分析之循环依赖及解决方案
Spring源码分析之循环依赖及解决方案 往期文章: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostPro ...
随机推荐
- 企业如何建立一体化数据分析平台?还是得说说那几家BI工具
近年来,BI工具和报表工具犹如一股春风,吹遍了大江南北,成为了众多企业的发展利器,受到了企业决策者的拥戴.同时,在企业信息化需求日益旺盛的市场里也孕育了不少BI工具与报表工具厂商.商业智能的应用在国外 ...
- windev的Trigger触发器,能秒SQL吗?
有朋友问,"你是不是在写论文?" (此处请想象个表情)"好吧,论文继续!" SQL中,触发器可以看成是一种特殊的存储过程,使用inserted临时表来建立数据关 ...
- Appium+ios环境搭建
appium 环境搭建 安装homebrew(Mac OSX上的软件包管理工具) $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubuse ...
- XML序列化与反序列化接口对接实战,看这篇就够了
关键字:c# .NET XML 序列化 反序列化 本文为接口对接实践经验分享,不对具体的XML概念定义进行阐述:涉及工具类及处理方法已在生产环境使用多年,可放心使用.当然如果你发现问题,或有不同想法, ...
- 舒服,给Spring贡献一波源码。
你好呀,我是歪歪. 这周我在 Spring 的 github 上闲逛的时候,一个 issues 引起了我的兴趣. 这篇文章,是我顺着这个 issues 往下写,始于它,但是不止于它: https:// ...
- elasticsearch高亮之词项向量
一.什么是词项向量 词项向量(term vector)是有elasticsearch在index document的时候产生,其包含对document解析过程中产生的分词的一些信息,例如分词在字段值中 ...
- 微服务从代码到k8s部署应有尽有大结局(k8s部署)
我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...
- 采用 DIV+CSS 布局网页练习
实验四:采用 DIV+CSS 布局网页练习 实验目的: 熟悉 DIV+CSS 布局网页的方法 实验要求: 1.制作一个完整网页和一个 css 文件: 2.在网页中采用 DIV+CSS 布局 4 个以上 ...
- [差分数组] LeetCode789 得分最高的最小轮调
LeetCode 得分最高的最小轮调 今天当然CV了因为今天比较忙,所以直接走算法,因为什么都不做的话并不符合社会主义核心价值观,今天小学一手查分数组. 题目:并不存在CV了还写什么题解 算法背景: ...
- k8s原来这么简单(一)核心组件与工作原理
k8s官方文档:https://kubernetes.io/zh/docs/home/ 前提 掌握容器技术:Docker,Containerd等 K8S优势 使用简单,少量人/小团队可以轻松维护大型 ...