通过JDK动态代理和自定义注解来控制方法级别的权限访问
2017-08-17 19:46
761 查看
自定义一个场景,玩电脑和睡觉,电脑只能是人玩,但是人,猫,狗都可以睡觉
这里将玩游戏和睡觉抽象出两个方法:
1.playComputer
2.sleep
将人和动物抽象出来成一个类:
1.Animal
但是怎么通过动态代理加自定义注解去让playComputer只能让人调用,sleep方法人,猫,狗都可以调用呢?
有个思路就是,在方法上面加注解,且注解的内容就是允许访问该方法的Animal的type,在调用这个playComputer或者sleep方法的时候进行拦截,并且取出被调用那个方法上面的注解值与调用对象Animal的type进行比对,如果包含就访问这个方法,如果不包含就不调用.
注意:这里使用的是jdk的动态代理,所以需要将注解放到接口上面,如果放到目标类的方法上面会导致读取不到,如果使用cglib的动态代理,当然那就不需要接口了,直接将注解放到目标类方法上面也能读取到注解的内容.
如下工程:
首先自定义注解,并且在里面定义人,猫,狗的常量:
将人,猫,狗抽象成Animal类:
接口类:
目标类:
关键的代理类,里面将被调用的方法上面的注解内容取出,和调用者的类型进行匹配:
测试主函数:
测试结果:
这里将玩游戏和睡觉抽象出两个方法:
1.playComputer
2.sleep
将人和动物抽象出来成一个类:
1.Animal
但是怎么通过动态代理加自定义注解去让playComputer只能让人调用,sleep方法人,猫,狗都可以调用呢?
有个思路就是,在方法上面加注解,且注解的内容就是允许访问该方法的Animal的type,在调用这个playComputer或者sleep方法的时候进行拦截,并且取出被调用那个方法上面的注解值与调用对象Animal的type进行比对,如果包含就访问这个方法,如果不包含就不调用.
注意:这里使用的是jdk的动态代理,所以需要将注解放到接口上面,如果放到目标类的方法上面会导致读取不到,如果使用cglib的动态代理,当然那就不需要接口了,直接将注解放到目标类方法上面也能读取到注解的内容.
如下工程:
首先自定义注解,并且在里面定义人,猫,狗的常量:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Secure { String[] values(); static String HUMAN = "HUMAN"; static String DOG = "DOG"; static String CAT = "CAT"; }
将人,猫,狗抽象成Animal类:
public class Animal { private String name; private String type; getter and setter... public String toString()...
接口类:
public interface Deal { @Secure(values = {Secure.HUMAN}) public String playComputer(Animal a); @Secure(values = {Secure.HUMAN, Secure.CAT, Secure.DOG}) public String sleep(Animal a); }
目标类:
public class DealImpl implements Deal { public String playComputer(Animal a) { String re = a + " playComputer, DealImpl方法"; System.out.println(re); return re; } public String sleep(Animal a) { String re = a + " sleep, DealImpl方法"; System.out.println(re); return re; } }
关键的代理类,里面将被调用的方法上面的注解内容取出,和调用者的类型进行匹配:
public class ProxyDeal implements InvocationHandler { private Object target; public Object bind(Object target) { this.target = target; Object targetProxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); return targetProxy; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Animal animal = null; Object result = null; if (null != args && args.length != 0) { animal = (Animal) args[0]; } if (method.isAnnotationPresent(Secure.class)) { Secure annotation = method.getAnnotation(Secure.class); String[] values = annotation.values(); if (null != values && values.length != 0) { for (String value : values) { if (value.trim().equals(animal.getType().trim())) { result = method.invoke(target, args); return result; } } System.out.println("禁止访问:" + animal); return null; } annotation.values(); } return result; } }
测试主函数:
public class SecureMain { public static void main(String[] args) { Deal deal = new DealImpl(); ProxyDeal proxy = new ProxyDeal(); Deal dealProxy = (Deal) proxy.bind(deal); Animal animal = new Animal("zhangsan", Secure.CAT); String re1 = dealProxy.playComputer(animal); String re2 = dealProxy.sleep(animal); System.out.println(re1 + " main"); System.out.println(re2 + " main"); } }
测试结果:
相关文章推荐
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- 通过使用反射+动态代理+注解来实现对事务的控制
- 自己试验在spring的环绕通知里获取目标对象的类名和目标方法的参数类名,用于根据自定义注解判断访问权限,有没有更好的办法,高手指点一下
- 通过SpringMVC+Annotation实现方法、按钮级别的细粒度权限控制
- 通过注解在方法级别上使用拦截器做登录权限校验
- spring mvc使用自定义注解控制访问权限
- SpringMVC给控制器添加自定义注解控制访问权限
- Struts2通过自定义标签实现权限控制的方法
- 使用动态代理+自定义注解控制数据库事务
- 通过 Zuul 代理控制报表访问权限
- 通过SpringMVC+Annotation实现方法、按钮级别的细粒度权限控制
- SpringMVC给控制器添加自定义注解控制访问权限
- Spring的AOP动态代理通过注解注入方法
- SpringMVC给控制器添加自定义注解控制访问权限(未测试)
- JAX-RPC学习笔记(2)-通过动态代理客户端访问webservice
- Java web自定义标签按钮级别权限控制完美诠释(jplogic 快速开发平台)
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- (来源不详 转载+整理)基于角色的访问控制方法(RBAC) 权限系统设计
- 一种基于注解的Spring MVC权限控制方法
- JDK动态代理中关于InvocationHandler中invoke()方法的调用问题