我和春天有个约会(三)
来源:互联网 发布:沈阳云优化软件 编辑:程序博客网 时间: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;
}
}
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 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");
}
}
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;
}
}
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();
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的影子……
- 我和春天有个约会(三)
- 我和春天有个约会
- 我和春天有个约会(一)
- 我和春天有个约会(二)
- 我和春天有个约会(四)
- 和春天有个约会
- 参加不愿让你一个人之我和春天有个约会的看法
- 我和.NET有个约会!!
- 我和英语有个约会
- 我和python有个约会
- 我和明星有个“约会”
- 我和书、有个约会。
- 我和气功有个约会
- 我和node.js有个约会
- 我和未来有个约会
- 我和夏天有个约会 2017.0711
- 我和奥运有个约会:我的奥运畅想
- 我和僵尸有个约会·僵尸游戏精选
- 鱼和水的故事--完整版
- Servlet/JSP配置详解
- 使用lomboz调试JSP
- 在Linux上架设支持JSP+PHP的Web服务器
- 匈奴的起源
- 我和春天有个约会(三)
- vs2005中发送邮件的方法(C#)
- 批量删除
- 批量修改(前提要改都改)
- java过滤器
- 成吉思汗统一蒙古
- NetBean5.0 连接 MySql5.02数据库
- 今天开了BLOG
- AnsiString学习之一,看到的是你想不到的。(C++Builder 6)