Spring AOP官方文档学习笔记(四)之Spring AOP的其他知识点

这篇具有很好参考价值的文章主要介绍了Spring AOP官方文档学习笔记(四)之Spring AOP的其他知识点。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.选择哪种AOP

(1) 使用Spring AOP比使用完整版的AspectJ更方便简单,因为不需要在开发和构建过程中引入AspectJ编译器以及织入器,如果我们只希望通知能够在Spring Bean上执行,那么选用Spring AOP就可以了,如果我们希望通知能够在不由Spring所管理的对象上执行,那么就需要使用AspectJ,如果我们希望为除方法以外的连接点(比如成员变量)提供通知,那么也需要使用AspectJ

2.Spring AOP的代理机制

(1) Spring AOP使用Jdk动态代理或Cglib动态代理来为目标对象创建代理对象,Jdk动态代理由Jdk提供,而Cglib动态代理则是由一个开源类库提供,如果要代理的目标对象至少实现了一个接口,那么就会使用Jdk动态代理,否则如果目标对象没有实现任何接口,那么就会使用Cglib动态代理,创建一个Cglib代理对象

(2) Spring默认使用Jdk动态代理,但我们可以强制让Spring始终使用Cglib动态代理,但需注意,使用Cglib动态代理,无法对final修饰的方法织入通知,因为这些方法不能在子类中被重写,具体开启Cglib动态代理的方式如下

<!-- 方式一:在使用基于xml的配置时,设置<aop:config/>标签中的proxy-target-class属性为true -->
<aop:config proxy-target-class="true">
        <!-- ... -->
</aop:config>

<!-- 方式二:在混合使用基于xml和注解的配置时,设置<aop:aspectj-autoproxy/>标签中的proxy-target-class属性为true -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<!-- 方式三:在使用基于注解的配置时,设置@EnableAspectJAutoProxy注解中的proxyTargetClass属性为true -->
@EnableAspectJAutoProxy(proxyTargetClass = true)

(3) 当一个bean被代理后,我们从容器中获取到这个bean,并对其使用 .getClass().getName() 方法来输出它的类名称,可见如 cn.example.spring.boke.ExampleA$$EnhancerBySpringCGLIB$$ff6c22d2或com.sun.proxy.$Proxy18 这样的输出,而当我们关闭掉AOP后,得到的通常是形如 cn.example.spring.boke.ExampleA 这样的输出,这其实是因为我们从容器中获取的是该bean被增强过后的代理对象,而非它原始的目标对象,因而,对这个bean的方法调用就是对代理对象的方法调用,然后由代理对象委托调用原始对象上相关的方法以及该方法相关的拦截器(advice),如下

Spring AOP官方文档学习笔记(四)之Spring AOP的其他知识点

(4) 在目标对象中,使用this指针进行自调用不会触发通知的执行

//一个普通的bean,在它的a方法中使用this指针,自调用b方法
@Component
public class ExampleA{
    public void a() {
        System.out.println("a...");
        this.b();
    }

    public void b() {
        System.out.println("b...");
    }
}

//切面,切入ExampleA这个bean中的所有方法
@Component
@Aspect
public class Logger {
    @Before(value = "execution(* cn.example.spring.boke.ExampleA.*(..))")
    public void beforePrint() {
        System.out.println("beforePrint...");
    }
}

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "cn.example.spring.boke")
public class Config { }

//获取ExampleA,调用a方法,打印结果
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
ExampleA exampleA = ctx.getBean(ExampleA.class);
exampleA.a();

//可见,Spring对a方法进行了织入,而b方法却没有,原因就是因为这里的this指向的是目标对象,一个普通的bean ExampleA,而非它的代理对象,自然而然无法进行织入了,因此关键的目标就是如何获取到代理对象
beforePrint...
a...
b...


//想要获取代理对象,首先要先将@EnableAspectJAutoProxy注解中的exposeProxy属性设置为true
@EnableAspectJAutoProxy(exposeProxy = true)

//接着修改ExampleA中的a方法,在调用b方法时不再使用this指针,而是AopContext.currentProxy(),即获取当前对象的代理对象
public void a() {
    System.out.println("a...");
//        this.b();
    ((ExampleA) AopContext.currentProxy()).b();
}

//接着,再执行打印,可见此时通知已被正确执行
beforePrint...
a...
beforePrint...
b...

Spring不推荐使用如上的方法,因为这会使Spring AOP与我们的代码强耦合,具有侵入性,最好的方式是重构我们的代码,避免发生自调用,此外,Spring AOP会产生这种问题的原因是Spring AOP是基于代理实现的,而AspectJ框架就不存在这种自调用问题,因为它不是一个基于代理的AOP框架

3.基于java代码的AOP文章来源地址https://www.toymoban.com/news/detail-437496.html

public class ExampleA{
    public void a() {
        System.out.println("a...");
    }
}

//切面必须由@Aspect注解标注,否则容器会抛出异常
@Aspect
public class Logger {
    @Before(value = "execution(* cn.example.spring.boke.ExampleA.*(..))")
    public void beforePrint() {
        System.out.println("beforePrint...");
    }
}

//创建AOP工厂,生成代理对象
public static void main(String[] args) throws Exception {
    //1.使用AspectJProxyFactory工厂,用于生成目标对象的代理对象
    AspectJProxyFactory factory = new AspectJProxyFactory(new ExampleA());

    //2.添加一个切面,该切面必须由@Aspect注解标注
    factory.addAspect(Logger.class);

    //3.生成代理对象
    ExampleA proxy = factory.getProxy();
    proxy.a();
}

到了这里,关于Spring AOP官方文档学习笔记(四)之Spring AOP的其他知识点的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring MVC官方文档学习笔记(二)之DispatcherServlet

    1.DispatcherServlet入门 (1) Spring MVC是以前端控制器模式(即围绕着一个中央的Servelt, DispatcherServlet)进行设计的,这个DispatcherServlet为请求的处理提供了一个共用的算法,即它都会将实际的请求处理工作委托给那些可配置的组件进行执行,说白了,DispatcherServlet的作用就是进行统一调度,并

    2024年02月07日
    浏览(79)
  • Spring MVC官方文档学习笔记(一)之Web入门

    注: 该章节主要为原创内容,为后续的Spring MVC内容做一个先行铺垫 1.Servlet的构建使用 (1) 选择Maven - webapp来构建一个web应用 (2) 构建好后,打开pom.xml文件,一要注意打包方式为war包,二导入servlet依赖,如下 (3) 替换webapp/WEB-INF/web.xml文件为如下内容,采用Servlet 3.1版本 (4) 在

    2024年02月03日
    浏览(42)
  • 后悔没早学这份Python神级文档!2023最新入门到进阶核心知识点学习文档!

    如今学 Python 的程序员越来越多,甚至不少人会把 Python 当作第一语言来学习。不过尽管 Python 功能强大上手轻松,但并不代表它的学习曲线不陡峭,得来全不费工夫。 当推开 Python 的大门,你会发现 Python 入门简单但精通很难。看似语法记得滚瓜烂熟,但一进入实际项目,就

    2024年02月06日
    浏览(48)
  • 学习笔记-elstaciElasticSearch7.17官方文档

    特征 适用于所有 Elasticsearch API 的强类型请求和响应。 所有 API 的阻塞和异步版本。 在创建复杂的嵌套结构时,使用流畅的构建器和功能模式允许编写简洁但可读的代码。 通过使用对象映射器(例如 Jackson 或任何 JSON-B 实现)无缝集成应用程序类。 将协议处理委托给一个 h

    2024年02月14日
    浏览(42)
  • Flink|《Flink 官方文档 - 部署 - 概览》学习笔记

    学习文档:《Flink 官方文档 - 部署 - 概览》 学习笔记如下: 上图展示了 Flink 集群的各个构建(building blocks)。通常来说: 客户端获取 Flink 应用程序代码,将其转换为 JobGraph,并提交给 JobManager JobManager 将工作分配给 TaskManager,并在那里执行实际的算子操作 在部署 Flink 时,

    2024年01月19日
    浏览(51)
  • Spring学习笔记(四)AOP介绍

            AOP的全称是Aspect Oriented Programming,即 面向切面编程 。和OOP(面向对象编程)不同,AOP主张将程序中相同的业务逻辑进行 横向隔离 ,并将重复的业务逻辑抽取到一个独立的模块中,以达到 提高程序可重用性和开发效率的目的 。                在传统的业务处理代

    2024年02月21日
    浏览(37)
  • Flink|《Flink 官方文档 - 内幕 - 文件系统》学习笔记

    学习文档:内幕 - 文件系统 学习笔记如下: Flink 通过 org.apache.flink.core.fs.FileSystem 实现了文件系统的抽象。这种抽象提供了一组通用的操作,以支持使用各类文件系统。 为了支持众多的文件系统, FileSystem 的可用操作集非常有限。例如,不支持对现有文件进行追加或修改。

    2024年02月03日
    浏览(35)
  • Spring5学习笔记—AOP编程

    ✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Spring专栏 ✨特色专栏: MySQL学习 🥭本文内容:Spring5学习笔记—AOP编程 🖥️个人小站 :个人博客,欢迎大家访问 📚个人知识库: 知识库,欢

    2024年02月12日
    浏览(37)
  • CSP初赛知识点 学习笔记

    对于咱们信奥选手来说,会做的题要坚决不丢分,不会做的题要学会尽量多拿分,这样你的竞赛之路才能一路亨通! 文件(文件夹)操作 点击查看代码 G++/Gcc 基础指令 访问速度:寄存器 () 高速缓存 () 内存(ROM + RAM) () 外存,断电仅保留 ROM 和外存中的数据。 (texttt

    2024年02月09日
    浏览(46)
  • ROS 2官方文档(基于humble版本)学习笔记(二)

    今天继续总结CLI 工具章的学习 理解节点(node) ROS 2图是一个ROS 2元件同时处理数据的网络,如果将它们全部映射并可视化它们,则包括所有可执行文件以及它们之间的连接。 ROS中的每个节点(node)都应该只为了单个的、模块化的目的而设计的,例如控制车轮电动机或从激光

    2024年02月10日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包