论坛首页 Java企业应用论坛

Annotation再阐释

浏览 7152 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-11  
OO
Annotation再阐释

论坛之前就有阐释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还可以更复杂,就不讨论了。

   发表时间:2007-05-11  
...总感觉annotation应该还可以更好的进行扩展和完善.
0 请登录后投票
   发表时间:2007-05-12  
对annotation不感冒,可能是还没有感受到它的好处,现在项目中,仍还是XML,相信其它朋友也是以XML配置居多吧。
0 请登录后投票
   发表时间: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配置
0 请登录后投票
   发表时间: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"/>  
0 请登录后投票
   发表时间:2007-05-12  
rainlife 写道
对annotation不感冒,可能是还没有感受到它的好处,现在项目中,仍还是XML,相信其它朋友也是以XML配置居多吧。

感觉要对annotation搞得好,很多时候ide也很重要的...
这一个问题论坛有一些帖子讨论了很多,挖一下坟就可以看到了..
0 请登录后投票
   发表时间: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持保留态度,但各人有各人的具体情况和用法
怎么方便怎么用吧,天下太平。。。
0 请登录后投票
   发表时间: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层的很少见!
0 请登录后投票
   发表时间: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();
    }

}
0 请登录后投票
   发表时间:2007-05-13  
这个东东应该用于做框架,搞点类似于AOP框架应该不错吧
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics