动态代理的两种实现方式

本文深入探讨了动态代理的两种实现方式:JDK动态代理和Cglib动态代理。JDK动态代理基于接口,通过反射机制创建匿名类实现接口,无需额外jar包;Cglib动态代理基于继承和动态编译,利用ASM包修改字节码生成子类,适用于未实现接口的类,但不适用于final类。

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

代理模式分为 静态代理 和 动态代理,今天我要讲的是动态代理的两种常见、也是被广泛使用的实现方式-------jdk动态代理 和 Cglib动态代理

第一种:JDK动态代理方式

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

/**
 * JDK动态代理
 * 一个类(Proxy)一个接口(InvocationHandler)
 * */
public class JDKProxy implements InvocationHandler{
	//真实主题对象
	private Object target;
	
	/**
	 * 给主题创建一个代理对象(基于接口实现)
	 * */
	public Object proxy(Object target){
		this.target = target;
		/*
		 * 1.类加载器
		 * 2.接口数组
		 * 3.InvocationHandler 对象
		 * */
		return Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				this);
	}
	/**
	 * proxy 代理对象
	 * method 当前执行的方法
	 * args 方法的参数数组
	 * */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//前置增强方法...
		System.out.println("前置增强方法");
		
		Object ret = method.invoke(target, args);
		
		//后置增强方法...
		System.out.println("后置增强方法");
		return ret;
	}

优点

  • 基于接口实现-----获取真实主题对象的接口,通过反射机制创建一个实现该接口的匿名类,在调用要增强的方法前调用InvacationHandler接口里的invoke方法。因为是jdk自带的功能,所以不需要额外导入第三方jar包

缺点

  • 不能对单个类(未实现接口)进行代理,因为jdk动态代理是基于接口实现

第二种:cglib动态代理方式

import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * Cglib动态代理	基于:1、继承	2、动态编译
 * 1、Enhancer类
 * 2、MethodInterceptor 方法拦截器  接口
 * */
public class CglibProxy implements MethodInterceptor{
	//真实主题对象
	private Object target;
	/**
	 * 给主题创建一个代理对象(基于继承实现)
	 * obj		代理主题
	 * method	调用方法	
	 * args		参数数组
	 * mp		代理方法
	 * */
	public Object proxy(Object target){
		this.target = target;
		
		Enhancer en = new Enhancer();
		en.setSuperclass(target.getClass());
		en.setCallback(this);
		return en.create();
	}
	
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
		//前置增强方法...
		System.out.println("前置增强方法");
		
		Object ret = mp.invoke(target, args);
		
		//后置增强方法...
		System.out.println("后置增强方法");
		return ret;
	}
	
}

优点

  • 基于类和继承实现----利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。功能十分强大,被代理的类可以不用实现接口,并且运行速度十分快

缺点

  • 在java中有一种类是无法被继承的,那就是用final关键字定义的类。而cglib动态代理是基于继承来实现的,所以它唯一的不足就在这里----无法对 final类 进行代理。此外,由于cglib是由第三方组织提供的,所以在使用的时候需要引入cglib的jar包(我这里是用的spring,它里面集成了cglib,若是单独使用cglib,可以直接去mvnrepository.com这个网站下载它的jar包)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值