Spring系列之Spring框架和SpringAOP集成过程分析(十二)

简介:

在这篇文章中我们接着上一篇的文章说。在上一篇文章中我们提到了getAdvicesAndAdvisorsForBean这个方法,这个方法的内容是为目标对象挑选合适的Advisor类,其源码如下:

    //targetSource 为null
    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        //如果获取的Advisor为空的话,则直接返回DO_NOT_PROXY 返回这个值的时候 是不创建代理对象
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //这个方法我们在上一章中分析过了   获取Spring容器中的所有的通知方法  封装为Advisor集合
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //这一步就是为目标对象挑选合适的Advisor 即目标对象和切点表达式相匹配
        //此处的分析  请参考这里:https://blog.csdn.net/zknxx/article/details/79735405
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //这个方法做的事是向 上一步获取到的Advisor中 插入ExposeInvocationInterceptor.ADVISOR 插在第一个位置
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            //排序  很复杂的实现  不说了  如果你对一个目标对象使用多个 相同类型的通知的话 请把这些通知放到不同的Aspect中,并实现Order接口或者使用Ordered注解标注顺序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

最后我们再看看目标对象的创建过程:

    //specificInterceptors 上面的方法中获取到的Advisor 
    //targetSource 为 new SingletonTargetSource(bean) 
    //将Spring容器中创建出来的bean封装为了SingletonTargetSource
    protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        //这里将目标Bean的Class设置为BeanDefinition中的一个属性 
        //在使用JDK动态代理的时候 可能会用到这个属性  https://stackoverflow.com/questions/45463757/what-is-interface-based-proxying
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }
        //这里创建了一个新的 ProxyFactory
        ProxyFactory proxyFactory = new ProxyFactory();
        //copy原类的配置 重写赋值的动作   单例变多例
        proxyFactory.copyFrom(this);
        //这里是 判断是否强制使用 cglib
        if (!proxyFactory.isProxyTargetClass()) {
            //这里 判断是 使用jdk动态代理 还是cglib代理
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //这里又重写构建了一次 Advisor  看看是否 设置了通用的拦截
        //这里讲所有的Advisor和配置的通用拦截都转换为了Advisor类型
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);
        }
        //targetSource 里是包含目标对象的
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //创建代理对象 关于创建代理对象的分析 请参考:https://blog.csdn.net/zknxx/article/details/79764107
        return proxyFactory.getProxy(getProxyClassLoader());
    }

好了,到此关于AOP的分析就先暂时告一段落了。

相关文章
|
10天前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
34 14
|
10天前
|
XML Java API
Spring Boot集成MinIO
本文介绍了如何在Spring Boot项目中集成MinIO,一个高性能的分布式对象存储服务。主要步骤包括:引入MinIO依赖、配置MinIO属性、创建MinIO配置类和服务类、使用服务类实现文件上传和下载功能,以及运行应用进行测试。通过这些步骤,可以轻松地在项目中使用MinIO的对象存储功能。
|
12天前
|
消息中间件 Java Kafka
什么是Apache Kafka?如何将其与Spring Boot集成?
什么是Apache Kafka?如何将其与Spring Boot集成?
43 5
|
17天前
|
SQL 自然语言处理 数据库
XiYan-SQL:一种多生成器集成的Text-to-SQL框架
XiYan-SQL 是一种创新的多生成器集成Text-to-SQL框架,通过M-Schema增强模型对数据库结构的理解,结合ICL与SFT方法提升SQL生成质量和多样性,经实验证明在多个数据集上表现优异,特别是在Spider和SQL-Eval上取得了领先成绩。
|
14天前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
22 1
|
17天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
31 2
|
15天前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
27 0
|
2月前
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
114 1
|
2月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
146 1
|
2月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
537 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具