JDK和CGLIB动态代理

JDK动态代理

特点

优点:jdk自带,不需导入jar包
缺点:真实对象必须实现接口、利用反射效率不高

实现步骤

①创建处理器:
需实现InvocationHandler接口,实现invoke方法(参数:代理对象,被代理方法,方法参数)
需持有真实对象,在invoke中通过method.invoke进行调用被代理方法

②生成代理对象:
proxy.newProxyInstance()
参数:
反射时需要的类加载器(两个类为同一个加载器)
代理对象实现接口(new Class[]{接口.class})
处理器

例:
具体类ReallObejct实现接口AllObject
①处理器

public class DynamicProObject implements InvocationHandler {

 	AllObject myObject; 
 	public DynamicProObject() {}
 	
 	public DynamicProObject(AllObject myObject) {
  		super();
  		this.myObject = myObject;
 	} 
 	
 	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  		System.out.println("ago thing");
  		method.invoke(myObject, args);
  		System.out.println("after thing");
  		return null; 
 	}
}

②生成代理对象

public static void main(String[] args) {
  	AllObject myObject = new ReallObject();
  	//生成处理器
  	DynamicProObject handler = new DynamicProObject(myObject);
  	//生成代理对象
  	AllObject neProxy = (AllObject)Proxy.newProxyInstance(
                       			ClassLoader.getSystemClassLoader(), 
                         			new Class[] {AllObject.class},handler);

	//测试代理
  	neProxy.oneThing();
  	
  	//测试出代理类的父类及接口
  	System.out.println(neProxy.getClass().getGenericSuperclass());
  	Type[] allInter = neProxy.getClass().getGenericInterfaces();
  	for (Type type : allInter) {
   		System.out.println(type);
  	} 
 }

③结果
在这里插入图片描述
Ps:这也就是具体类为什么要实现接口的原因:
        生成的代理类继承了Proxy类,而Java并不能多继承,使得代理类和具体必须实现一个共同的接口来产生联系

CGLIB动态代理

特点

优点:基于字节码(.class文件)效率高
缺点:第三方jar包(cglib、asm(字节码解析工具包))
实质:给需要代理的类生成一个子类,实现代理方法

实现步骤

①创建处理器:
需实现MethodInterceptor接口,实现intercept方法(参数:子类对象,被代理方法,方法参数,生成的子类代理方法)
调用被代理方法:父类方法.invoke(arg0,arg2)或子类方法.invokeSuper(arg0,arg2)

②生成代理对象(使用Enhancer类的对象):
设置父类:.setSupperclass(被代理类.class)
设置处理器:.setCallback(处理器对象)
生成对象:.create()

例:
①创建处理器

public class DynamicProCGLIB implements MethodInterceptor{
 	@Override
 	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
  		System.out.println("ago thing");
  		arg3.invokeSuper(arg0, arg2);
  		System.out.println("after thing");
  		return null;
 	}
}

②生成代理对象

public static void main(String[] args) {	
	//进行相关处理
  	Enhancer hancer = new Enhancer();
  	hancer.setSuperclass(ReallyCGLIB.class);
  	hancer.setCallback(new DynamicProCGLIB());
  	//生成子类对象
  	ReallyCGLIB eCglib = (ReallyCGLIB)hancer.create();
  	eCglib.one();
  	//测试出代理类的父类及接口
  	System.out.println(eCglib.getClass().getGenericSuperclass());
  	Type[] allInter = eCglib.getClass().getGenericInterfaces();
 	 for (Type type : allInter) {
   		System.out.println(type);
  	} 
 }

③结果
在这里插入图片描述
此处发现CGLIB的实质是创建了具体类的子类,并使其实现cglib动态代理工厂的接口,得以完成代理过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值