CGlib和JDK动态代理

本文详细介绍了JDK和CGLIB两种动态代理的实现方式,包括JDK基于接口的反射机制和CGLIB基于类的继承实现。JDK代理效率高但需目标对象实现接口,CGLIB效率低但无需接口,适用于无法实现接口的类。此外,还探讨了两者在实际应用中的选择和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CGlib和JDK动态代理

JDk动态代理基于接口实现

package com.xin.demo.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;


//代理模式:基于JDK反射机制:(Poxy类+InvocationHandler接口)
//通过接口实现:目标对象要实现接口

/*
*Mybatis框架底层,每次调用Mapper映射器时,使用该Mappper映射器的动态代理对象调用目标方法
*MapperProxyFactory(Proxy类创建Mapper的代理对象)
*MapperProxy(是InvocationHandler接口的实现类)
*
*/

public class JdkProxyFactory implements InvocationHandler{
	//定义目标对象
	private Object target;
	
	//构造方法传入目标对象
	public JdkProxyFactory(Object target) {
		super();
		this.target = target;
	}
	
	//创建代理对象
	public Object createProxy() {
		
		//获取目标对象Class对象
		 Class targetClass = target.getClass();
		 
		 //参数1:目标对象的Class对象的类加载器
		 //参数2:目标对象实现的接口(数组)
		 //参数3:InvocationHandler接口的实现类也就是当前类,代理对象调用目标方法时就到参数所在对象的invoke方法
		 Object newProxy = Proxy.newProxyInstance(targetClass.getClassLoader()
					 								, targetClass.getInterfaces()
					 								, this);
		 //返回代理对象	
		return newProxy;
		 
	}
	//proxy时当前产生的代理对象
	//method:传入的目标方法
	//args:目标方法的参数
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		System.out.println("***********增强功能**************");
		System.out.println("方法参数:"+Arrays.toString(args));
		
		
		System.err.println("目标方法:"+method);
		
		
		System.err.println("代理方法:");
		
		//完成目标方法的调用
		//method.invoke(target, args)参数:目标对象,目标对象方法参数
		Object invoke = method.invoke(target, args);
		
		
		
		return invoke;
	}

}

CGlib动态代理基于接口实现

package com.xin.demo.proxy;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

//代理模式:基于Cglib实现(Enhancer类+MethodInterceptor接口)
//基于继承实现
public class CglibProxyFactory implements MethodInterceptor{
	private Object target;
	
	public CglibProxyFactory(Object target) {
		super();
		this.target = target;
	}
	
	public Object createProxy() {
		Enhancer enhancer = new Enhancer();
		
		enhancer.setSuperclass(target.getClass());//传入目标类的Class对象,会自动寻找目标类父类
		
		//设置回调对象:当代理对象调用目标方法时,会执行对象的intercept方法
		enhancer.setCallback(this);//传入实现CallBack的实现类,当前类实现了MethodInterceptor,MethodInterceptor实现了CallBack
		Object create = enhancer.create();//创建代理对象
		return create;//返回代理对象
	}
	//当目标对象调用方法时,会将方法传入intercept中,method是传入目标方法,arg2是目标方法参数
	@Override
	public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("增强###################################");
		//执行标方法
		
		Object invoke = method.invoke(target, arg2);
		
		
		System.out.println("增强*****************************************");
		//方法返回值
		return invoke;
	}

}

两种代理的测试

package com.xin.demo.proxy;

import com.xin.dao.DemoDAOImpl;
import com.xin.dao.IDemoDAO;
//代理
public class DemoProxy implements IDemoDAO{
	private IDemoDAO idemo=new DemoDAOImpl();
	@Override
	public void executeInsert() {
		
		System.out.println("【增强】");
		idemo.executeInsert();
		
	}

	@Override
	public void executeUpdate() {
		System.out.println("【增强】");
		
		idemo.executeUpdate();
		
	}

}

JDK和CGLIB动态代理的区别

JDK代理使用的是反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGLIB代理使用字节码处理框架asm,对代理对象类的class文件加载进来,通过修改字节码生成子类。

JDK创建代理对象效率较高,执行效率较低;
CGLIB创建代理对象效率较低,执行效率高。

JDK动态代理机制是委托机制,只能对实现接口的类生成代理,通过反射动态实现接口类;
CGLIB则使用的继承机制,针对类实现代理,被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,因为是继承机制,不能代理final修饰的类。

JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,需要满足以下要求:
 1.实现InvocationHandler接口,重写invoke()
 2.使用Proxy.newProxyInstance()产生代理对象
 3.被代理的对象必须要实现接口
CGLib 必须依赖于CGLib的类库,需要满足以下要求:
 1.实现MethodInterceptor接口,重写intercept()
 2.使用Enhancer对象.create()产生代理对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值