/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
表示注解是否能被 javadoc 处理并保留在文档中。
2. 使用 元注解 来自定义注解 和 处理自定义注解
有了元注解,那么我就可以使用它来自定义我们需要的注解。结合自定义注解和AOP或者过滤器,是一种十分强大的武器。比如可以使用注解来实现权限的细粒度的控制——在类或者方法上使用权限注解,然后在AOP或者过滤器中进行拦截处理。下面是一个关于登录的权限的注解的实现:
/**
* 不需要登录注解
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoLogin {
}
我们自定义了一个注解 @NoLogin, 可以被用于 方法 和 类 上,注解一直保留到运行期,可以被反射读取到。该注解的含义是:被 @NoLogin 注解的类或者方法,即使用户没有登录,也是可以访问的。下面就是对注解进行处理了:
/**
* 检查登录拦截器
* 如不需要检查登录可在方法或者controller上加上@NoLogin
*/
public class CheckLoginInterceptor implements HandlerInterceptor {
private static final Logger logger = Logger.getLogger(CheckLoginInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
logger.warn("当前操作handler不为HandlerMethod=" + handler.getClass().getName() + ",req="
+ request.getQueryString());
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
String methodName = handlerMethod.getMethod().getName();
// 判断是否需要检查登录
NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);
if (null != noLogin) {
if (logger.isDebugEnabled()) {
logger.debug("当前操作methodName=" + methodName + "不需要检查登录情况");
}
return true;
}
noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);
if (null != noLogin) {
if (logger.isDebugEnabled()) {
logger.debug("当前操作methodName=" + methodName + "不需要检查登录情况");
}
return true;
}
if (null == request.getSession().getAttribute(CommonConstants.SESSION_KEY_USER)) {
logger.warn("当前操作" + methodName + "用户未登录,ip=" + request.getRemoteAddr());
response.getWriter().write(JsonConvertor.convertFailResult(ErrorCodeEnum.NOT_LOGIN).toString()); // 返回错误信息
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
}
}
上面我们定义了一个登录拦截器,首先使用反射来判断方法上是否被 @NoLogin 注解:
NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);
然后判断类是否被 @NoLogin 注解:
noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);