关于spring aop的应用参见:Spring AOP-基于@AspectJ风格

spring在初始化容器时就会生成代理对象:

关于创建bean的源码参见:Spring Boot源码(六):Bean的创建详解

我们进入createBean()的doCreateBean()方法:

其中的initializeBean():

其中的applyBeanPostProcessorsBeforeInitialization():

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException { Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

此方法是拿到各种各样的后置处理器,去处理对象。

再次加上条件断点:

第5个是我们处理aop的后置处理器。如果我们没有使用aop,那就没有它。

进入此类AbstractAutoProxyCreator的方法:

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

wrapIfNecessary()方法:

进入createProxy()方法:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

如果该类实现接口,用jdk代理,否则使用cglib代理,默认是jdk代理。

再来看getProxy():

它有两个实现类:

JdkDynamicAopProxy#getProxy()

public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

最后一行就是jdk代理的代码了。可见JDK动态代理

附debug流程图:

Spring Boot源码(八):Spring AOP源码的更多相关文章

  1. 快速开发架构Spring Boot 从入门到精通 附源码

    导读 篇幅较长,干货十足,阅读需花费点时间.珍惜原创,转载请注明出处,谢谢! Spring Boot基础 Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计 ...

  2. Spring Boot核心技术之Rest映射以及源码的分析

    Spring Boot核心技术之Rest映射以及源码的分析 该博客主要是Rest映射以及源码的分析,主要是思路的学习.SpringBoot版本:2.4.9 环境的搭建 主要分两部分: Index.ht ...

  3. Spring Boot 2.X(八):Spring AOP 实现简单的日志切面

    AOP 1.什么是 AOP ? AOP 的全称为 Aspect Oriented Programming,译为面向切面编程,是通过预编译方式和运行期动态代理实现核心业务逻辑之外的横切行为的统一维护的一 ...

  4. spring boot / cloud (十八) 使用docker快速搭建本地环境

    spring boot / cloud (十八) 使用docker快速搭建本地环境 在平时的开发中工作中,环境的搭建其实一直都是一个很麻烦的事情 特别是现在,系统越来越复杂,所需要连接的一些中间件也越 ...

  5. Spring Boot 必须先说说 Spring 框架!

    现在 Spring Boot 非常火,各种技术文章,各种付费教程,多如牛毛,可能还有些不知道 Spring Boot 的,那它到底是什么呢?有什么用?今天给大家详细介绍一下. Spring Boot ...

  6. spring boot 2.0.3+spring cloud (Finchley)3、声明式调用Feign

    Feign受Retrofix.JAXRS-2.0和WebSocket影响,采用了声明式API接口的风格,将Java Http客户端绑定到他的内部.Feign的首要目标是将Java Http客户端调用过 ...

  7. Spring Boot配置篇(基于Spring Boot 2.0系列)

    1:概述 SpringBoot支持外部化配置,配置文件格式如下所示: properties files yaml files environment variables command-line ar ...

  8. Spring Boot 2 (三):Spring Boot 2 相关开源软件

    Spring Boot 2 (三):Spring Boot 2 相关开源软件 一.awesome-spring-boot Spring Boot 中文索引,这是一个专门收集 Spring Boot 相 ...

  9. spring boot rest 接口集成 spring security(2) - JWT配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  10. Spring Boot 2(一):Spring Boot 2.0新特性

    Spring Boot 2(一):Spring Boot 2.0新特性 Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2 ...

随机推荐

  1. 【WPF学习】第三十六章 样式基础

    前面三章介绍了WPF资源系统,使用资源可在一个地方定义对象而在整个标记中重用他们.尽管可使用资源存储各种对象,但使用资源最常见的原因之一是通过他们的保存样式. 样式是可应用于元素的属性值集合.WPF样 ...

  2. Node.js实战--资源压缩与zlib模块

    Blog:<NodeJS模块研究 - zlib> Github:https://github.com/dongyuanxin/blog nodejs 的 zlib 模块提供了资源压缩功能. ...

  3. 微信小程序框架分析小练手(二)——天气微信小程序制作

    简单的天气微信小程序. 一.首先,打开微信开发者工具,新建一个项目:weather.如下图: 二.进入app.json中,修改导航栏标题为“贵州天气网”. 三.进入index.wxml,进行当天天气情 ...

  4. Linux文件和目录的属性及权限总结

    本文讲述的是文件或目录的属性及权限,比如索引节点inode.文件类型.文件权限及属主:还对setuid.setgid及粘贴位进行了相关的讲解.其中,对ln.chmod.chown.chgrp.umas ...

  5. 全局对象的构造函数会在main函数之前执行?

    #include <iostream> using namespace std; class CTest { public: CTest() { cout << "构 ...

  6. FFMPEG结构体分析:AVCodecParameters

    /** * This struct describes the properties of an encoded stream. * * sizeof(AVCodecParameters) is no ...

  7. Android: 关于WebView的loadData方法

    关于WebView的loadData方法 Author : Aoyousatuo Zhao http://blog.sina.com.cn/aoyousatuo WebView是Android应用开发 ...

  8. 🔥SpringBoot图文教程2—日志的使用「logback」「log4j」

    有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...

  9. Codeforces_739_B

    http://codeforces.com/problemset/problem/739/B dfs,记录距离前缀和,每次找到离最近的不符合的点. #include<iostream> # ...

  10. bzoj 50题纪念

    bzoj好难,边看题解边做终于水到了50t,不知道水平提没提高啊TAT