博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CGLib动态代理
阅读量:6644 次
发布时间:2019-06-25

本文共 3133 字,大约阅读时间需要 10 分钟。

 动态代理:

在程序执行时,运用反射机制动态创建代理类,不须要程序猿编写源码.动态代理简化了编程工作,提高了系统的可扩展性,由于Java反射机制能够生成随意类型的动态代理类.说究竟,java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力.

详细说来,JDK动态代理中包括一个Proxy类和一个InvocationHandler接口.

  • 通过Proxy类为一个或多个接口动态地生成实现类,其方法是:

public staticObject newProxyInstance(ClassLoader loader, Class
[] interfaces,InvocationHandler h) throws IllegalArgumentException{}

  • 通过InvocationHandler接口,调用实现类的方法,从而完毕终于操作.其方法是:

publicinterface InvocationHandler {publicObject invoke(Object proxy,Method method,Object[] args) throws Throwable;}

注意:以上说的是JDK的动态代理,JDK动态代理最大的缺点就是依靠接口实现,假设一些类没有接口,JDK动态代理就无能为力了。

面对JDK动态缺点,CGLib又发挥了它的如何优势呢?

CGLib动态代理包括MethodProxy、Proxy类和一个接口MethodInterceptor

  • 通过MethodProxy、Proxy类获得实现类,方法例如以下:

public Object invokeSuper(Object obj, Object[] args) throws Throwable {        try {            init();            FastClassInfo fci = fastClassInfo;            return fci.f2.invoke(fci.i2, obj, args);        } catch (InvocationTargetException e) {            throw e.getTargetException();        }    }

  • 通过MethodInterceptor接口拦截被代理对象的方法。从而完毕终于操作

public interface MethodInterceptor extends Callback{   public Object intercept(Object obj, java.lang.reflect.Method method,Object[] args,MethodProxy proxy) throws Throwable;}

 CGLib动态代理Demo:

没有实现接口的实现类:

//没有实现接口的打招呼类public class greetingimpl {	public void sayhello(String name) {		System.out.println(name+"  sayhello");	}}

CGLib动态代理类:

//CGLib动态代理类public class CGLibDynamicProxy  implements MethodInterceptor{	//单例模式创建代理对象	private static CGLibDynamicProxy instance=new CGLibDynamicProxy();			//空的构造方法	private CGLibDynamicProxy(){			}		//返回代理对象的实例	public static  CGLibDynamicProxy getInstance(){		return instance;	}		//获得被代理的对象	public 
T getProxy(Class
cls){ return (T) Enhancer.create(cls, this); } //拦截被代理对象的方法,在前后分别运行before()和after()方法 @Override public Object intercept(Object target, Method method, Object[] args,MethodProxy proxy) throws Throwable { before(); //Object result=proxy.invokeSuper(target, args);//方式一:这是CGLib动态代理比JDK动态代理方式多出来的方法,效率更高 //Object result=proxy.invoke(target, args);//方式二:使用该方法报"栈溢出"错:Exception in thread "main" java.lang.StackOverflowError Object result=method.invoke(target, args);//方式三:这是JDK动态代理中使用的方式 after(); return result; } //在代理类的方法的方法前运行 public void before(){ System.out.println("Before"); } //在代理类的方法的方法后运行 public void after(){ System.out.println("After"); }}

Client类:

public class client {	public static void main(String[] args) {		greetingimpl greetingimpl=CGLibDynamicProxy.getInstance().getProxy(greetingimpl.class);		greetingimpl.sayhello("CGLibDynamicProxy");	}}

打印结果:

有接口的实现类:

//实现接口的打招呼类public class greetingimpl implements greeting{	public void sayhello(String name) {		System.out.println(name+"  sayhello");	}}

Client类:

public class client {	public static void main(String[] args) {		greeting greeting=CGLibDynamicProxy.getInstance().getProxy(greetingimpl.class);		greeting.sayhello("CGLibDynamicProxy");	}}

使用同样的CGLib动态代理类

打印结果:

总结:

CGLib动态代理在JDK动态代理的的基础上了做了攻克了没有实现接口类的动态代理问题,其关键点体如今动态代理类所提供的方法的能力上稍做了些增强,能够说CGLib动态代理就是JDK动态代理的改进版。

转载于:https://www.cnblogs.com/clnchanpin/p/6912879.html

你可能感兴趣的文章
Weighted Effect Coding: Dummy coding when size matters
查看>>
Day15 - Python基础15 模块学习-selectors
查看>>
Nginx介绍及其环境搭建
查看>>
会话管理
查看>>
PHP7安装mysql扩展
查看>>
jQuery 隐藏/显示
查看>>
001 Math对象,数组和表的高级运用 字符串
查看>>
那些年一起用过的iOS开发利器之CocoaPods
查看>>
【转】Ubuntu11.10下安装Hadoop1.0.0(单机伪分布式)
查看>>
tcp_nodelay的作用
查看>>
echars 图表提示框自定义显示
查看>>
HLG 1543 序列难题[后缀数组]
查看>>
渲染流水线
查看>>
揭示同步块索引(中):如何获得对象的HashCode
查看>>
Python线程池及其原理和使用(超级详细)
查看>>
刷存在感-01
查看>>
在Linux里安装Samba(文件共享)方便在Windows下面操作
查看>>
PHP的两个科学计数法转换为字符串的方法
查看>>
iframe高度自适应
查看>>
shell中的流程控制
查看>>