Java:深入自定义注解(Annotation)

 在网上找了很多资料也有写的比较好的,但是总有有一点半点的细节没有写出来,在这里自己总结下使用。

 使用 Java 的自定义注解,首先个人需要了解下 Java 为我们提供的元注解和相关定义注解的语法。(这个我在网上选择了一篇详细的介绍链接在文章最底层)


 

1、首先自定义我们需要的注解

package com.plat;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*

  • @Retention(RetentionPolicy.SOURCE)

  • 这个注解的意思是让 MyAnnotation 注解只在 java 源文件中存在,编译成.class 文件后注解就不存在了

  • @Retention(RetentionPolicy.CLASS)

  • 这个注解的意思是让 MyAnnotation 注解在 java 源文件 (.java 文件) 中存在,编译成.class 文件后注解也还存在,

  • 被 MyAnnotation 注解类标识的类被类加载器加载到内存中后 MyAnnotation 注解就不存在了
    /
    /

  • 这里是在注解类 MyAnnotation 上使用另一个注解类,这里的 Retention 称为元注解。

  • Retention 注解括号中的 "RetentionPolicy.RUNTIME" 意思是让 MyAnnotation 这个注解的生命周期一直程序运行时都存在
    */
    //Target 注解决定 MyAnnotation 注解可以加在哪些成分上,如加在类身上,或者属性身上,或者方法身上等成分
    /**

  • @author jwkang
    是否需要判断权限,默认为 true 需要判断权限,设定为 false 的情况下不判断权限
    /
    @Documented
    @Inherited
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PlatPermission {

    boolean validate() default true;
    }

2、将自定义注解标识在不需要判断权限的方法上

    @PlatPermission(validate=false)
    @RequestMapping(value = "/getSelect", method = {RequestMethod.POST})
    @ResponseBody
    public BaseOutModel GetSelect(String selectType) {
        BaseOutModel result = new BaseOutModel();
        LinkedHashMap<String, String> data = new LinkedHashMap<String, String>();
        try {
        </span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">TypeOfEnum.contains(selectType))
        {
            result.setResult(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
            result.setErrorMessage(</span>"未找到对应信息"<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
        }
        TypeOfEnum typeOfEnum </span>=<span style="color: rgba(0, 0, 0, 1)"> TypeOfEnum.get(selectType);
        data </span>=<span style="color: rgba(0, 0, 0, 1)"> EnumHelp.getZEnumDesList(typeOfEnum.getType());
        result.setResult(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
        result.setResponse(data);
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        e.printStackTrace();
        logger.error(</span>"operateEmail err"<span style="color: rgba(0, 0, 0, 1)">, e.toString());
        result.setResult(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
        result.setErrorMessage(</span>"系统异常!请重试..."<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}</span></pre>

3、进行权限的管控

    jar 包的引用:

import org.springframework.web.method.HandlerMethod;

   权限的控制,注解读取

public class PlatHandlerInterceptorAdapter extends HandlerInterceptorAdapter {
    private static final ILog logger = LogManager.getLogger(PlatHandlerInterceptorAdapter.class);
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        </span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">处理Permission Annotation,实现方法级权限控制 
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">HandlerMethod 需要对应Jar包的位置,否则会一直为false</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span> (handler.getClass().isAssignableFrom(HandlerMethod.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">)) {
        HandlerMethod handlerMethod </span>=<span style="color: rgba(0, 0, 0, 1)"> (HandlerMethod) handler;
         </span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
         * 1、确认当前的controller是否需要进行权限判定,如果需要则进行验证。
         * 2、当controller不需要验证,则验证当前的方法是否需要权限验证,需要则进行验证,不需要则跳出
         * </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
        <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取controller注解, controller检查是否需要验证权限控制 </span>
        PlatPermission permission = handlerMethod.getMethod().getDeclaringClass().getAnnotation(PlatPermission.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (permission != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; !permission.validate()) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不需要验证权限</span>

{
return super.preHandle(request, response, handler);
}
//获取方法注解,方法检查是否需要验证权限控制
permission = handlerMethod.getMethod().getAnnotation(PlatPermission.class);
if (permission != null && !permission.validate()) //不需要验证权限
{
return super.preHandle(request, response, handler);
}
// 权限判断, 没有权限则跳转至无权限页面,有权限则走正常流程
xxxx
}

    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.preHandle(request, response, handler);
} 

}

4、完成,整个一套的注解使用


  深入 Java 注解(非常推荐):http://www.cnblogs.com/digdeep/p/4525567.html