博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java jdk与cglib动态代理模式的认识和实现
阅读量:6497 次
发布时间:2019-06-24

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

hot3.png

1.使用java jdk Proxy实现动态代理,该原理是反射机制。

建立一个普通的接口

package com.tester.cls.design.mode;public interface IUser {	public String getName();	public void setName(String name);		public void setUser(int id,String name);		public int getId();	public void setId(int id);}

构建一个实现类(简单的javaBean)

package com.tester.cls.design.mode;public class User  implements IUser{	private int id;		private String name;	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}		public void setUser(int id,String name) 	{		setId(id);		setName(name);	}		@Override	public String toString() {		return super.toString();	}	}

实现代理

InvocationHandler实质是拦截器,用来拦截动态代理的方法调用。

Proxy才是动态代理,拦截器拦截Proxy生成的代理对象的方法

package com.tester.cls.design.mode;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public  class ObjectProxy implements InvocationHandler{	IUser delegateTarget = null;		public  IUser delegate(IUser delegateTarget)	{		this.delegateTarget =  delegateTarget;		return  (IUser) Proxy.newProxyInstance(ObjectProxy.class.getClassLoader(), delegateTarget.getClass().getInterfaces(),this);	}		@Override	public Object invoke(Object proxy, Method method, Object[] args)			throws Throwable {		System.out.println(method.getName()+"-"+method.getReturnType());		return method.invoke(delegateTarget, args);	}	}

测试,测试一下

public static void main(String[] args) {				User u = new User();				ObjectProxy objHandler = new ObjectProxy();		IUser delegate = objHandler.delegate(u); //注意,返回值的类型是注解类型				delegate.setUser(2014, "zhangsan");				System.out.println(delegate.getId()+"-"+delegate.getName());		System.out.println(u.getId()+"-"+u.getName());				u.setUser(2048, "张三");				System.out.println(delegate.getId()+"-"+delegate.getName());		System.out.println(u.getId()+"-"+u.getName());		}

输出结果

2014-zhangsan2014-zhangsan2048-张三2048-张三

2.使用cglib.jar实现动态代理,原理是操作底层字节码

Cglib实现动态代理,Cglib的效率高于JDK动态代理,因为Cglib是有底层字节码方式生产一个代理类的(此观点来自于互联网,本人水平有限,目前只将概念)。

cglib使用底层ASM实现动态类的继承(很牛逼吧,我们日常使用的类是静态继承的,这简直是逆天的赶脚啊~~),能力好的童鞋建议去看源码。

(注:此处不提供 cglib.jar下载)

public class CglibProxy implements MethodInterceptor{ private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){  //设置需要创建子类的类  enhancer.setSuperclass(clazz);   enhancer.setCallback(this);  //通过字节码技术动态创建子类实例  return enhancer.create();  } //实现MethodInterceptor接口方法 public Object intercept(Object obj, Method method, Object[] args,   MethodProxy proxy) throws Throwable {  System.out.println("前置代理");  //通过代理类调用父类中的方法  Object result = proxy.invokeSuper(obj, args);  System.out.println("后置代理");  return result; }}

测试如下,但不提供结果

public class DoCGLib { public static void main(String[] args) {  CglibProxy proxy = new CglibProxy();  //通过生成子类的方式创建代理类  SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);  proxyImp.say(); }}

好了,这就是动态代理的基本认识

try doing it;

转载于:https://my.oschina.net/ososchina/blog/338821

你可能感兴趣的文章
Ubuntu系统在VMware虚拟机中显示显示过小
查看>>
关于swift使用CocoaPods倒入三方库的framework后父类倒入子类无法继承的问题
查看>>
PO设计模式
查看>>
WebGL Hello World Triangle Test
查看>>
第三周学习进度表
查看>>
[LeetCode]Perfect Squares
查看>>
[Heoi2013]Segment
查看>>
数据结构 队列的操作
查看>>
sqlDevelopor客户端操作MySQL数据库
查看>>
8.行命令按钮
查看>>
Codeforces Round #560 (Div. 3)
查看>>
android 网络小结
查看>>
信息安全C散列函数的应用及其安全性2016011992
查看>>
13、自平衡二叉查找树AVL
查看>>
浏览器兼容性参考【转】
查看>>
PAT 1030 Travel Plan[图论][难]
查看>>
greendao数据库初次使用的配置及多表关联的初始化
查看>>
【vue】vue中实现导出excel
查看>>
PHP页面跳转几种实现方法
查看>>
leetcode976
查看>>