Cglib实现动态代理原理

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

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

 

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

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

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

 

启动类:

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动态生成了一个新类字节码。

 

 

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值