Java动态代理(三)——Cglib动态代理
一、Cglib动态代理
Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用Cglib即使代理类没有实现任何接口也可以实现动态代理功能。而且,它的运行速度要远远快于JDK的Proxy动态代理。
1.Cglib核心类
- net.sf.cglib.proxy.Enhancer //主要的增强类
- net.sf.cglib.proxy.MethodInterceptor //主要的方法拦截类,它是Callback接口的子接口,需要用户实现。这个接口只定义了一个方法
- public Object intercept(Object object, java.lang.reflect.Method method,Object[] args, MethodProxy proxy) throws Throwable;//第一个参数是代理对像,第二和第三个参数分别是拦截的方法和方法的参数
- net.sf.cglib.proxy.MethodProxy //JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用
2.上篇PersonSerivice的Cglib代理实现(实现的前提是导入了Spring框架下的jar包)
被代理的类:
public class PersonServiceImp {
private String name;
private Integer age; public PersonServiceImp() {
super();
} public PersonServiceImp(String name, Integer age) {
super();
this.name = name;
this.age = age;
} public String getName() {
System.out.println("---------getName------");
return name;
} public Integer getAge() {
System.out.println("---------getAge--------");
return age;
} public void setName(String name) {
this.name = name;
} public void setAge(Integer age) {
this.age = age;
}
}
代理的类:
import java.lang.reflect.Method; import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; public class MyMethodInterceptor implements MethodInterceptor { @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if ("getName".equals(method.getName())) {
System.out.println("*********before*******");
System.out.println("method:" + method);
Object res = methodProxy.invokeSuper(obj, args);
System.out.println("*********after********");
return res;
} else {
Object res = methodProxy.invokeSuper(obj, args);
return res;
}
} }
测试:
import org.springframework.cglib.proxy.Enhancer; public class CglibProxyTest {
public static void main(String[] args) {
PersonServiceImp person = new PersonServiceImp();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(PersonServiceImp.class);
enhancer.setCallback(new MyMethodInterceptor());
person = (PersonServiceImp) enhancer.create();
person.setName("jack");
person.setAge(20);
System.out.println(person.getClass().getName());
System.out.println(person.getName());
System.out.println(person.getAge());
}
}
输出结果:
二、Jdk动态道理和Cglib动态代理的区别
1.JDK动态代理是利用反射机制实现的,在调用具体方法前调用InvokeHandler来处理。而Cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
2.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP,也可以强制使用CGLIB实现AOP;如果目标对象没有实现接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。
3.JDK动态代理只能对实现了接口的类生成代理,而不能针对类;CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法, 因为是继承,所以该类或方法不要声明成final。
4.使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。
Java动态代理(三)——Cglib动态代理的更多相关文章
- java的静态代理、jdk动态代理和cglib动态代理
Java的代理就是客户端不再直接和委托类打交道,而是通过一个中间层来访问,这个中间层就是代理.使用代理有两个好处,一是可以隐藏委托类的实现:二是可以实现客户与委托类之间的解耦,在不修改委托类代码的情况 ...
- Java代理(静态代理、JDK动态代理、CGLIB动态代理)
Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...
- Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。
借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...
- Spring <tx:annotation-driven>注解 JDK动态代理和CGLIB动态代理 区别。
基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...
- 浅谈Spring中JDK动态代理与CGLIB动态代理
前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...
- jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)
代理模式是一种很常见的模式,本文主要分析cglib动态代理的过程 1. 举例 使用cglib代理需要引入两个包,maven的话包引入如下 <!-- https://mvnrepository.c ...
- 静态代理、jdk动态代理、cglib动态代理
一.静态代理 Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求. RealSubject:具体主题角色,也叫被委托角色.被代理角色.是业务逻辑 ...
随机推荐
- 记一次针对静态页面的DDOS基本防护
可以说是我试图进入安全口的天才第一步了,能走多远鬼知道呢 背景 去年年前接到的一个外包项目,是一个base在日本的中国人留学机构做的静态页面.出于锻炼自己的目的,选择为他们按次结薪做长期服务维护.20 ...
- PHP atan2() 函数
实例 通过 atan2() 函数返回两个变量的反正切: <?phpecho(atan2(0.50,0.50) . "<br>");echo(atan2(-0.50 ...
- PHP mysqli_stat() 函数
创建 SSL 连接: <?php 高佣联盟 www.cgewang.com // 假定数据库用户名:root,密码:123456,数据库:RUNOOB $con=mysqli_connect(& ...
- 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘
一.前言 在项目的开发维护阶段,有时候我们关注的问题不仅仅在于功能的实现,甚至需要关注系统发布上线后遇到的问题能否及时的查找并解决.所以我们需要有一个好的解决方案来及时的定位错误的根源并做出正确及时的 ...
- RabbitMQ学习总结(3)-集成SpringBoot
1. pom.xml引用依赖 SpringBoot版本可以自由选择,我使用的是2.1.6.RELEASE,使用starter-web是因为要使用Spring的相关注解,所以要同时加上. <dep ...
- MyBatis-Plus使用(2)-CRUD接口
参考文档:https://mybatis.plus/guide/crud-interface.html MyBatis-Plus自带的CRUD方法分为Mapper层和Service层,大多数功能是重叠 ...
- 使用pytorch快速搭建神经网络实现二分类任务(包含示例)
使用pytorch快速搭建神经网络实现二分类任务(包含示例) Introduce 上一篇学习笔记介绍了不使用pytorch包装好的神经网络框架实现logistic回归模型,并且根据autograd实现 ...
- 【NOIP2017】跳房子 题解(单调队列优化线性DP)
前言:把鸽了1个月的博客补上 ----------------- 题目链接 题目大意:机器人的灵敏性为$d$.每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),m ...
- CSS漂亮盒子(上)
HTML文档中的所有元素都是由矩形盒子构成的--不管是包含页面结构的容器元素,还是段落中的每行文本,归根结底都是盒子. 1.背景颜色 设置页面背景颜色. body { background-color ...
- Python爬虫获取百度贴吧图片
#!/usr/bin/python# -*- coding: UTF-8 -*-import urllibimport re文章来源:https://www.cnblogs.com/Axi8/p/57 ...