第二十一章 Spring之假如让你来写AOP——Weaver(织入器)篇

Spring源码阅读目录

第一部分——IOC篇

第一章 Spring之最熟悉的陌生人——IOC
第二章 Spring之假如让你来写IOC容器——加载资源篇
第三章 Spring之假如让你来写IOC容器——解析配置文件篇
第四章 Spring之假如让你来写IOC容器——XML配置文件篇
第五章 Spring之假如让你来写IOC容器——BeanFactory和FactoryBean
第六章 Spring之假如让你来写IOC容器——Scope和属性填充
第七章 Spring之假如让你来写IOC容器——属性填充特别篇:SpEL表达式
第八章 Spring之假如让你来写IOC容器——拓展篇
第九章 Spring之源码阅读——环境搭建篇
第十章 Spring之源码阅读——IOC篇

第二部分——AOP篇

第十一章 Spring之不太熟的熟人——AOP
第十二章 Spring之不得不了解的内容——概念篇
第十三章 Spring之假如让你来写AOP——AOP联盟篇
第十四章 Spring之假如让你来写AOP——雏形篇
第十五章 Spring之假如让你来写AOP——Joinpoint(连接点)篇
第十六章 Spring之假如让你来写AOP——Pointcut(切点)篇
第十七章 Spring之假如让你来写AOP——Advice(通知)上篇
第十八章 Spring之假如让你来写AOP——Advice(通知)下篇
第十九章 Spring之假如让你来写AOP——番外篇:Spring早期设计
第二十章 Spring之假如让你来写AOP——Aspect(切面)篇
第二十一章 Spring之假如让你来写AOP——Weaver(织入器)篇
第二十二章 Spring之假如让你来写AOP——Target Object(目标对象)篇
第二十三章 Spring之假如让你来写AOP——融入IOC容器篇
第二十四章 Spring之源码阅读——AOP篇

第三部分——事务篇

第二十五章 Spring之曾经的老朋友——事务
第二十六章 Spring之假如让你来写事务——初稿篇
第二十七章 Spring之假如让你来写事务——铁三角篇
第二十八章 Spring之假如让你来写事务——属性篇
第二十九章 Spring之假如让你来写事务——状态篇
第三十章 Spring之假如让你来写事务——管理篇
第三十一章 Spring之假如让你来写事务——融入IOC容器篇
第三十二章 Spring之源码阅读——事务篇

第四部分——MVC篇

第三十三章 Spring之梦开始的地方——MVC
第三十四章 Spring之假如让你来写MVC——草图篇
第三十五章 Spring之假如让你来写MVC——映射器篇
第三十六章 Spring之假如让你来写MVC——拦截器篇
第三十七章 Spring之假如让你来写MVC——控制器篇
第三十八章 Spring之假如让你来写MVC——适配器篇
第三十九章 Spring之假如让你来写MVC——番外篇:类型转换
第四十章 Spring之假如让你来写MVC——ModelAndView篇
第四十一章 Spring之假如让你来写MVC——番外篇:数据绑定
第四十二章 Spring之假如让你来写MVC——视图篇
第四十三章 Spring之假如让你来写MVC——上传文件篇
第四十四章 Spring之假如让你来写MVC——异常处理器篇
第四十五章 Spring之假如让你来写MVC——国际化篇
第四十六章 Spring之假如让你来写MVC——主题解析器篇
第四十七章 Spring之假如让你来写MVC——闪存管理器篇
第四十八章 Spring之假如让你来写MVC——请求映射视图篇
第四十九章 Spring之假如让你来写MVC——番外篇:属性操作
第五十章 Spring之假如让你来写MVC——融入IOC容器篇
第五十一章 Spring之源码阅读——MVC篇

第五部分——Boot篇

第五十二章 Spring之再进一步——Boot
第五十三章 Spring之假如让你来写Boot——环境篇
第五十四章 Spring之假如让你来写Boot——注解篇(上)
第五十五章 Spring之假如让你来写Boot——注解篇(下)
第五十六章 Spring之假如让你来写Boot——SPI篇
第五十七章 Spring之假如让你来写Boot——配置文件篇(上)
第五十八章 Spring之假如让你来写Boot——配置文件篇(下)
第五十九章 Spring之假如让你来写Boot——番外篇:再谈Bean定义
第六十章 Spring之假如让你来写Boot——自动装配篇
第六十一章 Spring之假如让你来写Boot——番外篇:杂谈Starter
第六十二章 Spring之假如让你来写Boot——番外篇:重构BeanFactory
第六十三章 Spring之假如让你来写Boot——番外篇:再谈ApplicationContext
第六十四章 Spring之假如让你来写Boot——内嵌Web容器篇
第六十五章 Spring之假如让你来写Boot——Main方法启动篇
第六十六章 Spring之最终章——结语篇



前言

    对于Spring一直都是既熟悉又陌生,说对它熟悉吧,平时用用没啥问题,但面试的时候被问的一脸懵逼,就很尴尬,都不好意思在简历上写着熟悉Spring了
在这里插入图片描述

    所以决定花点时间研究研究Spring的源码。主要参考的书籍是:《Spring源码深度解析(第2版)》、《Spring揭秘》、《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》


    书接上回,在上篇 第二十章 Spring之假如让你来写AOP——Aspect(切面)篇 中,A君 已经完成了 Aspect(切面) 部分,对切点和通知进行了统一管理。接下来看看 A君 会有什么骚操作吧

尝试动手写IOC容器

    出场人物:A君(苦逼的开发)、老大(项目经理)

    背景:老大要求A君在一周内开发个简单的 IOC容器

    前情提要: A君 已经完成了 Aspect(切面) 部分,对切点和通知进行了统一管理 。。。

第二十一版 Weaver(织入器)篇

    “ A君,现在AOP部分已经快进入尾声了。还有个重要的部分——Weaver(织入器)。对于这部分内容,想必你或多或少都接触过。简而言之,就是创建代理对象,把对应的切面织入进去。当然啦,代理有基于JDK的,也有基于CGLIB的,这两个都要实现。A君,你有什么思路吗?” 老大 问到

    “那自然是定义个接口,包含创建代理的方法。接口代理也好,CGLIB代理也好,都遵循此接口。” A君 不假思索回答道

    “不错,可是这样子定义,使用者必须清楚代理有多少种实现,才能正确的创建出来代理对象!举个例子:以后新增一个创建代理的方式,那么使用者就得跟着改动,这在软件设计中可是大忌。创建代理中间是否少了点东西?” 老大 循循善诱道

    “工厂模式!?” A君 疑惑道

    “是的,你需要个工厂。使用者传入对应的配置信息即可,这样,即使以后有多少个实现,对于调用者来说是一样的,什么都不用改。除此之外,我看了你之前写的代码,缺少配置信息。我们可以根据是否存在接口,来推断使用哪个代理,但是不要剥夺用户自己指定配置的权利,这样用户没配置我们自己推断,配置了就以用户的为准,才能立于不败之地。” 老大 笑道

    “明白了!” A君 忽然有种醍醐灌顶的感觉:也许,任何设计都是被用户折腾出来的,逼得程序员处处考虑拓展性、灵活性

    “先这样子吧,你回去好好想想怎么做吧!” 老大 开始下逐客令

    “好的。” A君 默默的走回自己的工位。开始思索:如何实现 老大 所说的内容。后续创建代理都要依赖于配置,先从配置开始吧。可是配置要有哪些内容呢?A君 略一沉吟,列出下面几点:

  1. 是否使用类代理,在有接口的情况下,默认会使用JDK代理,但是保不准用户就是想用类代理
  2. 代理对象是否可见,正常情况下,代理对用户是黑盒,但是由于 AOP 存在自调用问题,即 this.xxx() 时切面无法正常执行,故而由此配置。例:

在这里插入图片描述
原因也简单,this是当前对象,也就是目标对象,没有经过代理对象,所以无法增强

  1. Advise 是否可见,默认为true
  2. 是否冻结,冻结后,配置无法再进行修改

A君 平时玩游戏时,总是选择简单难度,其实游戏本身是存在多种难度的,简单难度是面向普罗大众的,困难难度是为了给高玩提供的,各个阶层玩家都能有足够的游戏体验。这里配置也是一样的道理,对于普通用户来说,有些配置不需要去关心,想要掌控全部配置,那得对 AOP 有充足的认识才行。A君 定义 ProxyConfig 作为配置类,代码如下:

public class ProxyConfig {
   
    /**
     * advise是否可见
     */
    boolean opaque = false;
    /**
     * 允许代理对象内部通过 AopContext 访问当前代理,适用于自调用场景
     */
    boolean exposeProxy = false;
    /**
     * 是否使用CGLIB代理
     */
    private boolean proxyTargetClass = false;
    /**
     * 代理配置是否被冻结,防止运行时修改
     */
    private boolean frozen = false;

    public boolean isProxyTargetClass() {
   
        return this.proxyTargetClass;
    }

    public void setProxyTargetClass(boolean proxyTargetClass) {
   
        this.proxyTargetClass = proxyTargetClass;
    }


    public boolean isOpaque() {
   
        return this.opaque;
    }

    public void setOpaque(boolean opaque) {
   
        this.opaque = opaque;
    }

    /**
     * Return whether the AOP proxy will expose the AOP proxy for
     * each invocation.
     */
    public boolean isExposeProxy() {
   
        return this.exposeProxy;
    }

    public void setExposeProxy(boolean exposeProxy) {
   
        this.exposeProxy = exposeProxy;
    }

    public boolean isFrozen() {
   
        return this.frozen;
    }

    public void setFrozen(boolean frozen) {
   
        this.frozen = frozen;
    }

    public void copyFrom(ProxyConfig other) {
   
        this.proxyTargetClass = other.proxyTargetClass;
        this.exposeProxy = other.exposeProxy;
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穷儒公羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值