Cglib实现动态代理原理

本文介绍如何使用CGLIB动态代理技术在运行时为特定用户和方法添加权限过滤,避免修改原始代码,提高系统的灵活性和安全性。通过创建代理类、拦截器类和过滤器类,实现在不改变业务逻辑的情况下,对不同用户的不同操作进行权限控制。

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

我们可能会有这样的需求,系统已经上线运行了。但是需要对某些人和某些方法进行权限过滤。

例如:我们允许张三进行所有操作,包括增删改查,只允许其他用户查询。

首先想到的可能是,在每个方法中都加入逻辑判断,这样违背了开闭原则,极有可能引入其它错误。

那么我们可以使用动态代理的方式,在运行时动态的进行权限校验,不需要修改原先的逻辑代码,

只要通过增加动态代理类、拦截器类、拦截器类。如下例:

启动类:

package com.bj.belen.demo; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.NoOp; public class CGLIBTest { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Manager.class); enhancer.setCallbacks(new Callback[]{ new AuthProxy("张三"), NoOp.INSTANCE}); enhancer.setCallbackFilter(new AuthProxyFilter()); Manager m = (Manager) enhancer.create();//生成代理对象 m.add(); } }

权限过滤类:

package com.bj.belen.demo; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class AuthProxy implements MethodInterceptor { private String userName; public AuthProxy(String userName){ this.userName = userName; } public Object intercept(Object arg0, Method method, Object[] object, MethodProxy proxy) throws Throwable { System.out.println("begin auth"); if(!"张三".equals(this.userName)){ throw new RuntimeException("you don't have the authority"); } System.out.println("you have the authority"); return proxy.invokeSuper(arg0, object); } }

拦截器类:

package com.bj.belen.demo; import java.lang.reflect.Method; import net.sf.cglib.proxy.CallbackFilter; public class AuthProxyFilter implements CallbackFilter{ public int accept(Method arg0) { if(!"query".equalsIgnoreCase(arg0.getName())) return 0; return 1; } }

具体操作类:

package com.bj.belen.demo; public class Manager { public void query(){ System.out.println("begin query"); } public void delete(){ System.out.println("begin delete"); } public void update(){ System.out.println("begin update"); } public void add(){ System.out.println("begin add"); } }

在上述方法中,如果我们都去查询,那么将不会走权限过滤。否则如果是张三去添加,那么可以正常提交,会出现如下信息:
begin auth
you have the authority
begin add

否则会报出异常如下:

begin auth
Exception in thread "main" java.lang.RuntimeException: you don't have the authority
at com.bj.belen.demo.AuthProxy.intercept(AuthProxy.java:21)
at com.bj.belen.demo.Manager$$EnhancerByCGLIB$$4064f103.add(<generated>)
at com.bj.belen.demo.CGLIBTest.main(CGLIBTest.java:17)

其实现原理为:

在运行时动态生成代理类(该类继承了原有操作类),加入了权限拦截,并对某些方法不拦截。低层是使用ASM动态生成了一个新类字节码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值