JDK 和 CGLIB 实现动态代理

本文深入解析Java动态代理的两种实现方式:JDK Proxy和CGLIB。通过具体代码示例,详细介绍了如何使用JDK Proxy为实现了接口的类创建代理,以及如何利用CGLIB为未实现接口的类生成代理,实现方法的增强。

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

动态代理,可以理解为在不修改源码的情况下,对指定的方法进行增强。

JDK Proxy实现动态代理:被增强的类需要实现接口

public interface IUserDao {
	
	public void save();
	public void update();
	public void find();
	public void delete();
	
}
public class UserDaoImpl implements IUserDao {

	public void save() {
		System.out.println("save方法执行");
	}

	public void update() {
		System.out.println("update方法执行");
	}

	public void find() {
		System.out.println("find方法执行");
	}

	public void delete() {
		System.out.println("delete方法执行");
	}

}
public class UserDaoProxy  implements InvocationHandler{
	
	//需要传入要被增强的对象
	private IUserDao dao;
	
	public UserDaoProxy(IUserDao dao){
		this.dao = dao;
	}
	
	public IUserDao createProxy(){
		
		/*
		 * this:Proxy.newProxyInstance需要传入一个实现InvocationHandler的类
		 * 本例中UserDaoProxy  implements InvocationHandler 所以直接传入this
		 */
		return (IUserDao) Proxy.newProxyInstance(UserDaoProxy.class.getClassLoader(), dao.getClass().getInterfaces(),
				this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		if(method.getName().equals("save")){
			System.out.println("执行权限操作检验");
			Object obj = method.invoke(dao, args);
			return obj;
		}
		
		return method.invoke(dao, args);
	}
	
}
public class Demo4 {
	
	@Test
	public void test1(){
		IUserDao dao2 = new UserDaoImpl();
		UserDaoProxy proxy = new UserDaoProxy(dao2);
		IUserDao dao = proxy.createProxy();
		dao.save();
		dao.find();
		dao.update();
		dao.delete();
	}
	
}

执行Demo4:

 

CGLIB实现动态代理:被增强的类不需要实现任何接口

public class CustomerDao {
	public void save(){
		System.out.println("Customer save 方法执行");
	}
	
	public void update(){
		System.out.println("Customer update 方法执行");
	}
}
public class CglibProxyFactory  implements  MethodInterceptor {
	
	/*
	 * 不需要传入要被增强的对象
	 */
	
	public CustomerDao createProxy(){
		
		Enhancer enhancer = new Enhancer();
		
		enhancer.setSuperclass(CustomerDao.class);
		enhancer.setCallback(this);//其实就是传入 MethodInterceptor接口,底层回调 intercept方法
		
		Object obj = enhancer.create();
		return (CustomerDao)obj;
	}

   /*
     @param proxy "this", the enhanced object
     @param method intercepted Method
     @param args argument array; primitive types are wrapped
     @param methodProxy used to invoke super (non-intercepted method); may be called
   */
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		
		if(method.getName().equals("update")){
			
			/*
			 * 写成 method.invoke(proxy, args) 会报错
			 */
			Object invoke = methodProxy.invokeSuper(proxy, args);
			System.out.println("执行日志记录");
			
			return invoke;
		}
		
		return methodProxy.invokeSuper(proxy, args);
	}
	
}
public class Demo5 {
	
	@Test
	public void test1(){
		CglibProxyFactory fac = new CglibProxyFactory();
		CustomerDao proxy = fac.createProxy();
		proxy.save();
		proxy.update();
	}
	
}

执行Demo5:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值