浏览 7189 次
锁定老帖子 主题:Annotation再阐释
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-11
论坛之前就有阐释Annotation的: <实战篇:设计自己的Annotation>http://www.iteye.com/topic/36659 我这里结合我的使用情况,简单再阐释一下: Annotation能够对程序注入另外外的信息,有三个级别:代码级别,编译级别,运行时级别。 加注了Annotation的程序就是向三个级别“通知”你对“它”的“说明/注解” 比如: java.lang.Override是代码级别的注解,你加注了,如果IDE支持这个“说明”,他能够知道你认为这个方法覆盖了父类。一旦该方法因为名字写错了,IDE能够知道你错误了。 javax.persistence.OneToMany是运行时级别的注解,你加注了,JPA能够知道你加注的目标是一个1对n的关系,并把你设定在这个方法上的OneToMany的注解信息读取出来是用,比如cascade策略,fetche策略,从而被JPA知道,让JPA知道不正是你的目的? 编译器的Annotation我没有用过,但与此类推,就是告知编译器我们对这个类、方法、字段等等的“说明”,编译器可以据此作一些你设定的处理。 Annotation在角色上分为:定义者、注解者、读者(我自己的语言,千万别被我悟倒) 定义者:定义Annotation类型。根据需要,任何人都可以创建新的Annotation. 比如你可能定义一个方法上注解叫:Permission,运行期级别。 注解者:是用已经定义的Annotation,只要定义了Annotation,你便可以使用它进行注解。比如 @Permission("/root/forum/java/post") 你定义了Annotation,并且对是用它用来注解。可是程序怎么知道按照我的意思执行它? 读者:读取你的Annotation说明,按照你的要求作事情。如果这个Annotation是由你自己来定义,那么这个读者也要由你实现。 我以Permission为示例如何实现一个读者: 1、实现一个PermissionInterceptor(extends MethodInvocation),当被拦截的方法注解了Permission,则调用权限中心判断当前调用者是否有该权限。 如何判断是否加注了Permission?-->Permission permission = method.getAnnotation(Permission.class); permission不为null便是。 如和知道当前调用者?-->参考ThreadLocal的使用 2、把PermissionInterceptor配置通过Spring或者其他支持AOP的容器中 3、配置哪些bean需要通过PermissionInterceptor拦截 这样一个Annotation例子就完整了。之后你认为那个方法要权限验证,就只需要加个Permission注解就可以了。 这个例子比较简单,权限验证的Annotation还可以更复杂,就不讨论了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-05-11
...总感觉annotation应该还可以更好的进行扩展和完善.
|
|
返回顶楼 | |
发表时间:2007-05-12
对annotation不感冒,可能是还没有感受到它的好处,现在项目中,仍还是XML,相信其它朋友也是以XML配置居多吧。
|
|
返回顶楼 | |
发表时间:2007-05-12
引用 1、实现一个PermissionInterceptor(extends MethodInvocation),当被拦截的方法注解了Permission,则调用权限中心判断当前调用者是否有该权限。
如何判断是否加注了Permission?-->Permission permission = method.getAnnotation(Permission.class); permission不为null便是。 如和知道当前调用者?-->参考ThreadLocal的使用 2、把PermissionInterceptor配置通过Spring或者其他支持AOP的容器中 3、配置哪些bean需要通过PermissionInterceptor拦截 楼主的这个例子算是annotation的动态应用了吧,运行时判断有无权限 感觉还是比较方便 但是annotation做静态配置,感觉不是特别好。如 struts2的action配置 |
|
返回顶楼 | |
发表时间:2007-05-12
Qieqie 写道 1、实现一个PermissionInterceptor(extends MethodInvocation),当被拦截的方法注解了Permission,则调用权限中心判断当前调用者是否有该权限。 如何判断是否加注了Permission?-->Permission permission = method.getAnnotation(Permission.class); permission不为null便是。 如和知道当前调用者?-->参考ThreadLocal的使用 2、把PermissionInterceptor配置通过Spring或者其他支持AOP的容器中 3、配置哪些bean需要通过PermissionInterceptor拦截 举一下简单例子,你这里说的,类似这样的吗: public class AuthorityInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { HttpServletRequest request = null; ActionMapping mapping = null; Object[] args = invocation.getArguments(); for (int i = 0 ; i < args.length ; i++ ) { if (args[i] instanceof HttpServletRequest) request = (HttpServletRequest)args[i]; if (args[i] instanceof ActionMapping) mapping = (ActionMapping)args[i]; } if ( request.getSession().getAttribute("adminname") != null) { return invocation.proceed(); } else { return mapping.findForward("login"); } } } 配置: <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>/vaiiduser</value> <value>/admin</value> <value>/phone</value> </list> </property> <property name="interceptorNames"> <list> <value>authorityInterceptor</value> </list> </property> </bean> <bean id="authorityInterceptor" class="org.mmc.utils.AuthorityInterceptor"/> |
|
返回顶楼 | |
发表时间:2007-05-12
rainlife 写道 对annotation不感冒,可能是还没有感受到它的好处,现在项目中,仍还是XML,相信其它朋友也是以XML配置居多吧。
感觉要对annotation搞得好,很多时候ide也很重要的... 这一个问题论坛有一些帖子讨论了很多,挖一下坟就可以看到了.. |
|
返回顶楼 | |
发表时间:2007-05-13
我的代码不在Web层,而在Bo层,参考如下:
public class PermissionInterceptor implements MethodInterceptor { //PermissionManager提供权限验证服务,判断某人是否有某权限,他是个接口,定义了assertHasPermission方法 private PermissionManager permissionManager; //getter,setter of permissionManager public Object invoke(MethodInvocation invocation) throws Throwable { //Context封装了ThreadLocal,保存当前操作者Id,由Filter在请求进入的时候根据Session情况写入 Long userId = Context.getCurrentUserId(); Method method = invocation.getMethod(); Permission permission = method.getAnnotation(Permission.class); if (permission != null) { if (userId == null) { //请求者还没有登录,允不允许他访问呢? //code goes here, e.g: throw new LoginRequiredException(); } String permissionStr = permission.value(); //permissionManager负责验证是否有权限,如果没有权限,抛出ForbiddenException permissionManager.assertHasPermission(userId, permissionStr); } return invocation.proceed(); } } ForbiddenException和LoginRequiredException都是PermissionException的子类。 web层可以统一定制如果出现了PermissionException异常,则进行相关提示。 整个设计思路来源于Spring的 “事务管理器 + 事务拦截器” 模式,只是引入了Annotation而已。 了解到javaeye之前很多人对Annotation持保留态度,但各人有各人的具体情况和用法 怎么方便怎么用吧,天下太平。。。 |
|
返回顶楼 | |
发表时间:2007-05-13
Qieqie 写道 我的代码不在Web层,而在Bo层,参考如下:
public class PermissionInterceptor implements MethodInterceptor { //PermissionManager提供权限验证服务,判断某人是否有某权限,他是个接口,定义了assertHasPermission方法 private PermissionManager permissionManager; //getter,setter of permissionManager public Object invoke(MethodInvocation invocation) throws Throwable { //Context封装了ThreadLocal,保存当前操作者Id,由Filter在请求进入的时候根据Session情况写入 Long userId = Context.getCurrentUserId(); Method method = invocation.getMethod(); Permission permission = method.getAnnotation(Permission.class); if (permission != null) { if (userId == null) { //请求者还没有登录,允不允许他访问呢? //code goes here, e.g: throw new LoginRequiredException(); } String permissionStr = permission.value(); //permissionManager负责验证是否有权限,如果没有权限,抛出ForbiddenException permissionManager.assertHasPermission(userId, permissionStr); } return invocation.proceed(); } } ForbiddenException和LoginRequiredException都是PermissionException的子类。 web层可以统一定制如果出现了PermissionException异常,则进行相关提示。 整个设计思路来源于Spring的 “事务管理器 + 事务拦截器” 模式,只是引入了Annotation而已。 了解到javaeye之前很多人对Annotation持保留态度,但各人有各人的具体情况和用法 怎么方便怎么用吧,天下太平。。。 昨晚那么晚还上技术论坛,头脑这么清楚的? "//Context封装了ThreadLocal,保存当前操作者Id,由Filter在请求进入的时候根据Session情况写入 Long userId = Context.getCurrentUserId(); " Context的代码可否贴一小段出来,用Annotation在Bo层的很少见! |
|
返回顶楼 | |
发表时间:2007-05-13
Annotation天然和AOP具有合作精神(在我看来实在是绝配),AOP多用在Bo层的多,所以annotation在Bo层应用是自然而然的。
以下的Context代码,也是仅供参考(没有在eclipse调试,语法错误可能在所难免) public class Context { private static ThreadLocal<Long> currentUsers = new ThreadLocal<Long>(); private Context(){} //这个方法由Filter在请求达到时根据会话(e.g HttpSession,但不限于HttpSession)情况调用设置 public static void setCurrentUserId(Long userId) { currentUsers.set(userId); } //这个方法,可被同一JVM中的任何其他方法调用。 //返回当前请求者的Id,没有登录,则返回null public static Long getCurrentUserId() { return currentUsers.get(); } } |
|
返回顶楼 | |
发表时间:2007-05-13
这个东东应该用于做框架,搞点类似于AOP框架应该不错吧
|
|
返回顶楼 | |