我和春天有个约会(三)

来源:互联网 发布:沈阳云优化软件 编辑:程序博客网 时间:2024/03/29 19:31
  
小亮同志的疑惑,权限判断代码蛮横地渗透进纯洁的业务逻辑之中,有什么好办法让权限判断走远点呢?
AOP前传——代理机制
距离产生美……
将logging/Security等周边逻辑等巧妙地分离出主体业务逻辑,一方面让对象责任明确各司其职,提高可维护性;另一方面让它们召之即来挥之即去,修改更加方便。自然先想到Java I/O惯用的Decorate模式。人家早就总结了,叫做“静态代理”,并在此基础上推出了“动态代理”。
要是真用Decorate(静态代理)做权限判断,那乐子可就大了。假设我有五个class,每个class平均有五个函数需要获得相应权限才能进入,那么我就要做五个interface,每个interface平均五个接口函数对应那些函数,另外我需要五个proxy class,这些proxy class要定义对上述每个函数的权限判断包装。Wow,大大不妙,如黑土大叔对白云大妈的抱怨,距离有了,美没了。
而对于Java I/O,接口函数位于底层jdk中,被各种业务逻辑反复调用,且无外乎read/readln/write/writeln等,用Decorate还是值得的。
把目光转向动态代理。首先定义权限控制类RightsSet,每当用户进入系统就会创建该类对象以标示权限:
public class RightsSet {
    
public static final int NO_RIGHT = -1;
    
public static final int LOW_RIGHT = 0;
    
public static final int HIGH_RIGHT = 1;
    
    
private String name = "hezh";
    
private int right = LOW_RIGHT;
    
public RightsSet(String name, int x) {
        
this.name = name;
        
if(x < 5{
            right 
= NO_RIGHT;
        }
 else if(x >= 5 && x < 10){
            right 
= LOW_RIGHT;
        }
 else {
            right 
= HIGH_RIGHT;
        }

    }

    
    
public boolean isHighRight() {
        
return (right == HIGH_RIGHT);
    }

    
    
public boolean isLowRight() {
        
return (right == LOW_RIGHT);
    }

    
    
public String getName() {
        
return name;
    }

}

 
权限定义了三个级别:no-right/low-right/high-right;
业务逻辑的接口IMyBiz:
public interface IMyBiz {
    
public void biz_no_right();
    
public void biz_low_right();
    
public void biz_hight_right();
    
public void biz_no_right1();
    
public void biz_low_right1();
    
public void biz_hight_right1();
}

 
函数名暗含了三种权限,分别为:均可进入/低权限即可进入/高权限方可进入,实现它的业务逻辑如下:
public class MyBiz implements IMyBiz {
    
    
public void biz_no_right() {
        System.out.println(
"Any one here");
    }

    
    
public void biz_low_right() {
        System.out.println(
"Some one with low rights here");
    }

    
    
public void biz_hight_right() {
        System.out.println(
"Some one with hight here");
    }

    
    
public void biz_no_right1() {
        System.out.println(
"Any one here 111");
    }

    
    
public void biz_low_right1() {
        System.out.println(
"Some one with low rights here 111");
    }

    
    
public void biz_hight_right1() {
        System.out.println(
"Some one with hight here 111");
    }

}

 
花样在动态代理类中,每当遇到难题,java反射机制总是冲过来排忧解难,这次也不例外。jdk早就在反射中留好了动态代理接口InvocationHandler,我们实现它即可:
public class RightHandler implements InvocationHandler {
    
private RightsSet rights_set = null;

    
private Object delegate = null;

    
public Object bind(Object delegate, RightsSet rights_set) {
        
this.rights_set = rights_set;
        
this.delegate = delegate;
        
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
                delegate.getClass().getInterfaces(), 
this);
    }


    
public Object invoke(Object proxy, Method method, Object[] args)
            
throws Throwable {
        Object result 
= null;
        String[] low_right_methods 
= "biz_low_right""biz_low_right1" };
        String[] no_right_methods 
= "biz_no_right""biz_no_right1" };
        String[] high_right_methods 
= "biz_hight_right""biz_hight_right1" };
        String method_name 
= method.getName();

        
for (int i = 0; i < low_right_methods.length; i++{
            
if (method_name.equals(low_right_methods[i])) {
                
if (rights_set.isLowRight() || rights_set.isHighRight()) {
                    result 
= method.invoke(delegate, args);
                }
 else {
                    System.out.println(rights_set.getName() 
+ "对函数"
                            
+ method_name + "权限不够");
                }

                
return result;
            }

        }

        
        
for(int i = 0; i < no_right_methods.length; i ++{
            
if (method_name.equals(no_right_methods[i])) {
                result 
= method.invoke(delegate, args);
                
return result;
            }

        }

        
        
for (int i = 0; i < high_right_methods.length; i++{
            
if (method_name.equals(high_right_methods[i])) {
                
if (rights_set.isHighRight()) {
                    result 
= method.invoke(delegate, args);
                }
 else {
                    System.out.println(rights_set.getName() 
+ "对函数"
                            
+ method_name + "权限不够");
                }

                
return result;
            }

        }


        
return result;
    }


}

 
其中关键就是用bind函数实现代理和业务逻辑的绑定,用InvocationHandler的接口函数invoke具体实现权限管理以及对业务逻辑开展的影响。测试程序为:
// No rights-user
        System.out.println("For tom...");
        RightsSet rights_set1 
= new RightsSet("Tom"3);
        IMyBiz tom_biz 
= (IMyBiz) new RightHandler().bind(new MyBiz(),
                rights_set1);
        tom_biz.biz_hight_right();
        tom_biz.biz_low_right();
        tom_biz.biz_no_right();
        
        
// Low right-user
        System.out.println("For Jerry...");
        RightsSet rights_set2 
= new RightsSet("Jerry"9);
        IMyBiz jerry_biz 
= (IMyBiz) new RightHandler().bind(new MyBiz(),
                rights_set2);
        jerry_biz.biz_hight_right1();
        jerry_biz.biz_low_right1();
        jerry_biz.biz_no_right1();
        
        
// High right-user
        System.out.println("For Lucy...");
        RightsSet rights_set3 
= new RightsSet("Lucy"12);
        IMyBiz lucy_biz 
= (IMyBiz) new RightHandler().bind(new MyBiz(),
                rights_set3);
        lucy_biz.biz_hight_right1();
        lucy_biz.biz_low_right();
        lucy_biz.biz_no_right1();
 
其中Tom是no-right用户,Jerry是low-right用户,Lucy是high-right用户,结果如下:
For tom...
Tom对函数biz_hight_right权限不够
Tom对函数biz_low_right权限不够
Any one here
For Jerry...
Jerry对函数biz_hight_right1权限不够
Some one with low rights here 111
Any one here 111
For Lucy...
Some one with hight here 111
Some one with low rights here
Any one here 111
可以看到三个人权限一个高于一个。
总结一下动态代理的优势:比较好的实现了权限管理等非主体业务逻辑和主体业务逻辑的分离,并将这些非主体逻辑集中到InvocationHandler一并处理(针对静态代理的优势),最终提高了可维护性。
有了点 AOP的影子……
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 请问09年途锐柴油版怎么办 油电混合没电了怎么办 前向运动精子3%怎么办 精子活力正常精子活率低怎么办? 精子形态正常率低怎么办 前向运动精子20%怎么办 不运动精子率高怎么办 前向运动精子少怎么办 精子前向运动力低怎么办 精子异常形态率高怎么办 精子正常率才1%怎么办 精子头部缺陷率高怎么办 前向运动精子15%怎么办 精子向前运动力低怎么办 前向运动精子10%怎么办 前向运动精子12%怎么办 前向运动精子2%怎么办 正常精子形态只有10%怎么办 精子混合畸形率高怎么办 正常形态精子才2怎么办 精子密度低至0.8怎么办 精子总活动率低怎么办 前向运动精子低怎么办 精子畸形率百分之94怎么办 实验室授权签字人考不过怎么办 万和热水器排污口漏水怎么办 万和热水器水箱漏水怎么办 军训鞋大了怎么办妙招 麽稍神经不好受怎么办 绒面高跟鞋太硬怎么办 新买的鞋子太硬怎么办 鞋底太硬脚掌疼怎么办 耐克鞋子走路吱吱响怎么办 两只鞋子有色差怎么办 劳保鞋鞋底太硬怎么办 在学校校服丢了怎么办 高中没进重点班怎么办 孩子不懂学不想学怎么办 孩子小学数学学不懂怎么办 入学籍系统提交了没分班怎么办 被监考老师抓了作弊怎么办