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

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

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

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

其中的initializeBean():

其中的applyBeanPostProcessorsBeforeInitialization():

  1. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  2. throws BeansException {
  3.  
  4. Object result = existingBean;
  5. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  6. Object current = processor.postProcessAfterInitialization(result, beanName);
  7. if (current == null) {
  8. return result;
  9. }
  10. result = current;
  11. }
  12. return result;
  13. }

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

再次加上条件断点:

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

进入此类AbstractAutoProxyCreator的方法:

  1. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  2. if (bean != null) {
  3. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  4. if (this.earlyProxyReferences.remove(cacheKey) != bean) {
  5. return wrapIfNecessary(bean, beanName, cacheKey);
  6. }
  7. }
  8. return bean;
  9. }

wrapIfNecessary()方法:

进入createProxy()方法:

  1. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
  2. if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
  3. Class<?> targetClass = config.getTargetClass();
  4. if (targetClass == null) {
  5. throw new AopConfigException("TargetSource cannot determine target class: " +
  6. "Either an interface or a target is required for proxy creation.");
  7. }
  8. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
  9. return new JdkDynamicAopProxy(config);
  10. }
  11. return new ObjenesisCglibAopProxy(config);
  12. }
  13. else {
  14. return new JdkDynamicAopProxy(config);
  15. }
  16. }

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

再来看getProxy():

它有两个实现类:

JdkDynamicAopProxy#getProxy()

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

最后一行就是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. Linux学习笔记-centos查看版本号和内核信息

    1.查看centos系统版本号: 打开终端窗口: cat /etc/redhat-release 2.查看Linux内核版本信息: uname -a 或者 在图形化桌面右上角点开设置,在设置窗口选择详 ...

  2. Windows10怎么用Administrator登录?

    1.首先按下快捷键win+X键, 2.然后在命令提示符中输入命令“net user administrator /active:yes”后回车 3.此时administrator管理员账户已开启,点击 ...

  3. DotNetty发送请求的最佳实践

    长链接发送request/response时, 绝大部分包都是小包, 而每个小包都要消耗一个IP包, 成本大约是20-30us, 普通千兆网卡的pps大约是60Wpps, 所以想要提高长链接密集IO的 ...

  4. Java12可用新特性一览,了解一下没有错

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  5. js小练习---实现红绿灯

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Codeforces_334_C

    http://codeforces.com/problemset/problem/334/C 求不能凑整n,和最小,数量最多的数量. #include<iostream> #include ...

  7. POJ_1221_DP

    http://poj.org/problem?id=1221 简单dp,dp[i][j]表示i被划分成首位>=j的方案数. dp[i][i]为1,i为偶数时dp[i][i/2]为2. 剩下的可以 ...

  8. 第3章 JDK并发包(二)

    3.1.2 重入锁的好搭档:Condition条件 它和wait()和notify()方法的作用是大致相同的.但是wait()和notify()方法是和synchronized关键字合作使用的,而Co ...

  9. Qt使用双缓冲绘图时报错:pure virtual method called

    这个问题折磨了我将近四个小时. 起始原因是想写一个双缓冲绘图的画板,大概看了一下网上的教程,理解双缓冲绘图的思想后,没有完全参照网上的步骤,想着用自己的思路实现一下.(其实和网上的教程也没有太大差别) ...

  10. [redis读书笔记] 第二部分 集群

    1. 一个集群会包含多个节点(一个节点就是一个reid是服务器),CLUST MEET <ip><port>可以添加一个node到集群,命令执行后,两个node之间就会进行握手 ...