Spring框架中的JDK与CGLib动态代理
JDK和CGLib动态代理区别
JDK动态代理:利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,
在调用具体方法前调用InvokeHandler来处理。
CGLib动态代理:利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
何时使用JDK和CGLib:
1)如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP。
3)如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换。
如何强制使用CGLib实现AOP:
1)添加CGLIB库(aspectjrt-xxx.jar、aspectjweaver-xxx.jar、cglib-nodep-xxx.jar)
2)在Spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK动态代理和CGLib字节码生成的区别:
1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,
并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,
对于final类或方法,是无法继承的。
)当Bean实现接口时,Spring就会用JDK的动态代理。
2)当Bean没有实现接口时,Spring使用CGlib是实现。
3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)
代码测试如下:
我们先创建一个接口及其类
//接口类
package com.zzj.math; public interface IMathService { int add(int a,int b);
int div(int a,int b); } //及其类
package com.zzj.math; import org.springframework.stereotype.Service; @Service
public class MathService implements IMathService{ @Override
public int add(int a, int b) {
return a+b;
} @Override
public int div(int a, int b) {
return a/b;
} }
再创建一个代理类:
package com.zzj.aop; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; @Aspect
@Component
public class MethodAop { @Before("execution(public int com.zzj.math.MathService.*(..))")
public void before(JoinPoint jp){
Signature signature = jp.getSignature();
System.out.println("The "+signature.getName()+"method begins.");
} }
spring中xml的配置:
<!--扫描-->
<context:component-scan base-package="com.zzj"></context:component-scan>
<!-- proxy-target-class为true时根据目标类来创建代理类,也就是CGlib代理,当不写或者为false时根据目标类接口来进行代理,也就是JDK代理 -->
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
测试:
默认使用JDK代理,而且需要获取的bean必须是接口
package com.zzj.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zzj.math.IMathService;
public class Test {
public static void main(String[] args){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
IMathService mathService = applicationContext.getBean(IMathService.class);
System.out.println(mathService.getClass());
applicationContext.close();
}
}

当要强制使用CGLib时,我们将spring中xml的配置其对应标签属性改为true
<aop:aspectj-autoproxy proxy-target-class="true"/>)
测试类中获取的bean既可以是类也可以是接口,测试结果如下:

两种代理与目标类的关系
CGLib动态代理对象所产生的代理类是目标类的子类
System.out.println(mathService.getClass().getSuperclass());

JDK动态代理产生而的代理类与目标类没有继承关系
Class clazz = mathService.getClass();
Class [] array = clazz.getInterfaces();
for(Class c: array){
System.out.println(c.getName());
}

AOP中隐含的动态代理
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!--AOP代理-->
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
测试结果如下:

Spring框架中的JDK与CGLib动态代理的更多相关文章
- Spring AOP中的JDK和CGLib动态代理哪个效率更高?
一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...
- Spring AOP中的JDK和CGLIB动态代理
Spring在将Advice织入目标对象的Joinpoint是在运行时动态进行的.它采用的方式可能有两种,即JDK动态代理与CGLIB代理.Spring会根据具体的情况在两者之间切换. 实际情况如下: ...
- spring框架中JDK和CGLIB动态代理区别
转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/ ...
- 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)
Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC 目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...
- 【java高级编程】JDK和CGLIB动态代理区别
转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言 JDK动态代理实现原理(jdk8):https://blog.csdn.net ...
- JDK、CGlib动态代理详解
Java动态代理之JDK实现和CGlib实现(简单易懂) 一 JDK和CGLIB动态代理原理 1.JDK动态代理 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生 ...
- JDK和CGLIB动态代理原理
1.JDK动态代理利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类, 在调用具体方法前调用InvokeHandler来处理. 2.CGLiB动态代 ...
- JDK和CGLIB动态代理原理区别
JDK和CGLIB动态代理原理区别 https://blog.csdn.net/yhl_jxy/article/details/80635012 2018年06月09日 18:34:17 阅读数:65 ...
- JDK和CGLIB动态代理区别
背景:虽然自己了解这两种代理的区别,但是面试时候还是答的很模糊,需要好好总结. 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/de ...
随机推荐
- NAT-T和PAT(IPSec)
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥NAT-T技术介绍¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ 为什么TCP和UDP不能穿越:TCP和UDP有一个IP头的尾部校验(校验头部和负载 ...
- 结对编程任意Android App Demo
一.产品说明 1.编写目的:用于获取百度图标. 2.情景设计:本产品用于展示图标.随着21世纪各类元素的普及,大部分的人群想下载各类网站的图标,也为了方便用户更便捷的下载而开发的. 3.Demo主要实 ...
- Codeforces Round #616 (Div. 2) D
莫队的模板 struct node{ int l,r,id; }q[maxn]; int cmp(node a,node b) { ) ? a.r < b.r : a.r > b.r); ...
- codeforces Round #611
这种凌晨场真的折寿 就过了四题,8wa结尾心态炸裂,求别被hack,再hack就要爬了 A2 B8 C38(1) E1:58(7) D题感觉可以写,但是没有时间看了.幸好E最后发现了自己的 ...
- 利用ProxySQL实现MySQL的读写分离
本文简单介绍ProxySQL的安装及如果实现后端MySQL主从结构的读写分离. 一.ProxySQL安装 Proxy官方地址:https://proxysql.com/ proxysql-2.0.8- ...
- float元素上-margin的用法
css标准,float元素上的负margin表示把下面的元素向对应方向移动,并且覆盖上一个元素(这里是指html中元素的声明顺序). 标准情况下我们用float 时候是这样的. -margin通俗点说 ...
- KEAZ128 时钟配置
本文介绍如何用KEAZ128评估版(FRDM-KEAZ128Q80)配置为40MHz core freqency/20MHz bus frequency. 1.了解器件时钟特性 参见NXP KEA12 ...
- CSV文件自动化(自定义参数)
说明: CSV 文件:cmd_list1.csv testcase:对应test case id function:对应test case的标题 interfacenotes:对应bsp节点名称 cm ...
- [转]JSP自定义标签
原文链接 当jsp的内置标签和jstl标签库内的标签都满足不了需求,这时候就需要开发者自定义标签. 自定义标签 下面我们先来开发一个自定义标签,然后再说它的原理吧! 自定义标签的开发步骤 步骤一 编写 ...
- python 基础之集合
集合 s=set('chen xi') s1=['cx','ee','cx'] s2=set(s1)#set为集合 print(s2,type(s2)) s=list(s2) print(s,type ...