浅谈Java代理二:Cglib动态代理-MethodInterceptor

CGLib动态代理特点

使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

示例业务逻辑:

1-有一个明星叫胡歌(class HuGe)

3-找明星做事情需要经过助理(ProxyFactory )

4-如果要找胡歌唱歌、演戏,需要先找助理,然后助理去找胡歌唱歌、演戏(class testProcyFactory)

1-被代理类(没有实现任何接口)

package com.huishe.testOfSpring.methodinterceptor;

public class HuGe {

    public void sing(String song) {
System.out.println("胡歌演唱: " + song);
} public String act(String teleplay) {
System.out.println("胡歌决定出演电视剧: " + teleplay);
return "胡歌答应出演电视剧: " + teleplay;
}
}

2-代理工厂(即创建代理的通用写法)

package com.huishe.testOfSpring.methodinterceptor;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class ProxyFactory implements MethodInterceptor{
//要代理的原始对象
private Object object; //1-创建代理对象
public Object createProcy(Object target){
this.object = target;
//1-Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展
Enhancer enhancer=new Enhancer();
//2-将被代理类HuGe设置成父类
enhancer.setSuperclass(this.object.getClass());
//3-设置拦截器
enhancer.setCallback(this);
//4-动态生成一个代理类
Object objProxy = enhancer.create(); return objProxy; } //2-实现MethodInterceptor的intercept方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before: " + method);
//调用proxy.invoke()方法,会报java.lang.StackOverflowError错误,原因是invoke()内部会一直被反复调用
//Object object = proxy.invoke(obj, args);
Object object = proxy.invokeSuper(obj, args);
System.out.println("after: " + method);
return object;
}
}

3-进行测试

package com.huishe.testOfSpring.methodinterceptor;

import org.junit.Test;

import net.sf.cglib.proxy.Enhancer;

public class cglibMethodInterceptorTest {

    @Test
public void testProcyFactory(){
//1-实例化需要被代理的类
HuGe huGe = new HuGe();
//2-实例化代理工厂
ProxyFactory cglibProxy = new ProxyFactory();
//3-动态生成一个代理类,并从Object强制转型成父类型HuGe
HuGe hg =(HuGe)cglibProxy.createProcy(huGe); //4-执行动态代理类的方法
hg.sing("逍遥叹");
hg.act("琅琊榜"); } }

4-测试结果

日志输出:

before: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
胡歌演唱: 逍遥叹
after: public void com.huishe.testOfSpring.methodinterceptor.HuGe.sing(java.lang.String)
before: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)
胡歌决定出演电视剧: 琅琊榜
after: public java.lang.String com.huishe.testOfSpring.methodinterceptor.HuGe.act(java.lang.String)

参考资料

1-https://blog.csdn.net/jiaotuwoaini/article/details/51675684
2-https://www.cnblogs.com/writeLessDoMore/p/6973853.html

浅谈Java代理二:Cglib动态代理-MethodInterceptor的更多相关文章

  1. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  2. Java代理(静态代理、JDK动态代理、CGLIB动态代理)

    Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...

  3. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  4. JDK动态代理、CGLIB动态代理详解

    Spring的AOP其就是通过动态代理的机制实现的,所以理解动态代理尤其重要. 动态代理比静态代理的好处: 1.一个动态代理类可以实现多个业务接口.静态代理的一个代理类只能对一个业务接口的实现类进行包 ...

  5. jdk动态代理与cglib动态代理例子

    1.JAVA的动态代理特征:特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象 ...

  6. 代理模式详解:静态代理+JDK/CGLIB 动态代理实战

    1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...

  7. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

  8. JDK 动态代理与 CGLIB 动态代理,它俩真的不一样

    摘要:一文带你搞懂JDK 动态代理与 CGLIB 动态代理 本文分享自华为云社区<一文带你搞懂JDK 动态代理与 CGLIB 动态代理>,作者: Code皮皮虾 . 两者有何区别 1.Jd ...

  9. 代理模式 & Java原生动态代理技术 & CGLib动态代理技术

    第一部分.代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...

  10. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

随机推荐

  1. ISPF常用命令

    [ISPF功能键] PF1: HELP帮助键 PF2: SPLIT键,改变分屏位置 PF3: END键,结束并退回上级菜单 PF4: RETURN键,结束并退回主菜单 PF5: REFIND键,重复最 ...

  2. unity admob

    插件地址:https://github.com/unity-plugins/Unity-Admob 2017.04.11测试使用发现GoogleMobileAds.framework有问题,导致出现U ...

  3. 1.13.Mark1

    [经济学人]双语阅读:律师事务所 标价更高 收益更少 Business 商业报道   Law firms 律师事务所   Charging more, getting less 标价更高,收益更少 L ...

  4. Haskell语言学习笔记(74)GADTs

    GADTs GADTs(Generalised Algebraic Data Types,广义代数数据类型)是对代数数据类型的一种扩展. 它允许在定义数据类型时明确指定类型参数的类型并使用模式匹配. ...

  5. Linux性能测试分析命令_sar

    sar主要用于收集并统计系统资源的信息,包括CPU.IO.内存.网卡流量等. sar语法 用法:sar [ 选项 ] [ <时间间隔> [ <次数> ] ] 常用选项说明: - ...

  6. npm run dev 报错:missing script:dev

    一.问题: 今天在运行vue项目时,在mac终端输入npm run dev,结果报错: 翻译是: npm错误:缺少script:dev npm错误:完整路径见:users/mymac/ .npm/_l ...

  7. mysql 存储过程小问题

    mysql写的存储过程的一些小问题 DELIMITER $$ USE `yzhoteldb`$$ DROP PROCEDURE IF EXISTS `yz_waveData`$$ CREATE DEF ...

  8. ERROR: dump failed because assets could not be loaded

    在命令行输入命令,想查看到app的包名,报错,如下: D:\测试\测试\android-sdk_r16-windows\android-sdk-windows\platform-tools>aa ...

  9. R语言-直方图

    1.直方图 直方图和柱形图的区别:直方图表示频数,柱形图表示数量. 一般直方图的X轴表示取值范围,Y轴表示频数 hist() 函数 > hist(rnorm(1000)) #1000个正态随机数 ...

  10. 关于php laravel5.1框架出现路由找不到的情况

    开启apache模块在apache配置文件LoadModule rewrite_module modules/mod_rewrite.so前面的#去掉然后修改 vim  /etc/init.d/htt ...