关于spring aop两种代理混用的问题

 更新时间:2021年11月24日 15:01:47   作者:babyLetsGo  
这篇文章主要介绍了关于spring aop两种代理混用的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

spring aop两种代理混用问题

工作繁忙,但是遇到问题还是要总结积累下来,今天项目中出现了代理混用的问题,解决之后记录一下对两种代理方式的学习理解。

一、首先复习一下两种代理

JDK动态代理 和 cglib代理

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

Spring AOP的原理是 JDK 动态代理和CGLIB字节码增强技术,前者需要被代理类实现相应接口,也只有接口中的方法可以被JDK动态代理技术所处理;后者实际上是生成一个子类,来覆盖被代理类,那么父类的final方法就不能代理,因为父类的final方法不能被子类所覆盖。一般而言Spring默认优先使用JDK动态代理技术,只有在被代理类没有实现接口时,才会选择使用CGLIB技术来实现AOP。

但是也提供了配置参数来强制选择使用 CGLIB 技术,如下:

<aop:config proxy-target-class="true" /> 

proxy-target-class="true" 表示强制使用 CGLIB 技术来实现AOP,因为CGLIB是生成子类也就是代理类来实现的,所以proxy-target-class,表示是否代理目标类。<aop:config /> 就会由spring来选择,spring优先使用JDK动态代理来实现AOP。

二、我们项目是spring-boot项目

默认即为proxy-target-class="true",service实现类使用@service注解后都是使用CGLIB代理。

我遇到问题是,service某个方法添加@Async注解使该方法可异步调用,然后原有从spring容器中获取Bean对象的方法运行时就报错了,原来这个service实现类就不在使用CGLIB而是直接使用JDK动态代理。时间紧迫,具体原因后续再次分析,今天的记录就先到这里。

spring的aop和代理模式理解

Spring的AOP:即面向切面编程,其代码实质,即代理模式的应用。

代理模式代码的主要特点是

不改变原有类的前提下,在原有类某些方法执行前后,插入任意代码。所以代理模式需要写新的类对原有的类进行包装。

代理模式目前实现的方式有三种

  • 静态代理:需要增强原有类的哪个方法,就需要对在代理类中包装哪个方法。个人理解,从功能上来说,原有类和代理类不一定要实现共同接口,但是为了赋予代理和和被代理类之间的逻辑关系,增加程序的可读性,可理解性,逻辑性,增加代理对象和被代理对象之间的关系,以更加符合面向对象编程是思维,而应该实现共同接口。
  • 动态代理:使用反射机制,方法和对象都是传入的变量,就可以经过传入的对象和方法而动态调用被代理对象的任何方法,jdk中提供了实现此动态代理的api,被代理类必须实现接口
  • Cglib代理:返回对象是代理对象的子类,不需要代理对象实现接口。当调用原对象方法时,实际上调用的是代理子类的方法。

Aop的最大意义是

在不改变原来代码的前提下,也不对源代码做任何协议接口要求。而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码。

Struts2中的拦截器,spring中的赖加载都是用代理模式实现

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅谈java中String StringBuffer StringBuilder的区别

    浅谈java中String StringBuffer StringBuilder的区别

    下面小编就为大家带来一篇浅谈java中String StringBuffer StringBuilder的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • mybatis注解与xml常用语句汇总

    mybatis注解与xml常用语句汇总

    最近一直在用mybatis,由于需要使用到了动态sql,遇到了一些问题,现在来总结一下,经验教训。下面这篇文章主要给大家总结介绍了mybatis注解与xml常用语句的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-09-09
  • Spring定时任务注解@Scheduled详解

    Spring定时任务注解@Scheduled详解

    这篇文章主要介绍了Spring定时任务注解@Scheduled详解,@Scheduled注解是包org.springframework.scheduling.annotation中的一个注解,主要是用来开启定时任务,本文提供了部分实现代码与思路,需要的朋友可以参考下
    2023-09-09
  • 解决mybatis映射结果集失效的问题

    解决mybatis映射结果集失效的问题

    这篇文章主要介绍了解决mybatis映射结果集失效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 基于Idea+Jconsole实现线程监控步骤

    基于Idea+Jconsole实现线程监控步骤

    这篇文章主要介绍了基于Idea+Jconsole实现线程监控功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • java控制台实现聊天程序

    java控制台实现聊天程序

    这篇文章主要为大家详细介绍了java控制台实现聊天程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • java list去重操作实现方式

    java list去重操作实现方式

    Java中的List是可以包含重复元素的(hash code 和equals),接下来将介绍两种方式实现java list去重操作,感兴趣的朋友可以参考下
    2012-12-12
  • java中Integer包装类装箱的一个细节详解

    java中Integer包装类装箱的一个细节详解

    Java中的Integer是int的包装类型,下面这篇文章主要给大家介绍了关于java中Integer包装类装箱的一个细节的相关资料,文中介绍的这个细节挺重要的,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧
    2018-07-07
  • Java面向对象之类的继承介绍

    Java面向对象之类的继承介绍

    大家好,本篇文章主要讲的是Java面向对象之类的继承介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • file.mkdir()、file.mkdirs()和file.createNewFile()的区别

    file.mkdir()、file.mkdirs()和file.createNewFile()的区别

    本文主要介绍了file.mkdir()、file.mkdirs()和file.createNewFile()的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04

最新评论