1、 定义一个注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {
public String name() defalut "";
}
定义一个注解,其中包含一个参数name,默认为“”。
@Target – 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性,那么你需要在定义target包含所有的属性。
- ElemenetType.CONSTRUCTOR 构造器声明
- ElemenetType.FIELD 域声明(包括 enum 实例)
- ElemenetType.LOCAL_VARIABLE 局部变量声明
- ElemenetType.METHOD 方法声明
- ElemenetType.PACKAGE 包声明
- ElemenetType.PARAMETER 参数声明
- ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括
- RetentionPolicy.SOURCE 注解将被编译器丢弃
- RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
- RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
@Documented 将此注解包含在 javadoc 中
更多详见:
2、 定义好了,我们就可以在方法上使用@Auth(“zhangsan”)
3、 如何实现呢,这里我们通过Spring拦截器(拦截器用法google吧)进行的操作,看下代码
public class ParamInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1、Class.isAssignableFrom()作用与instanceof相似,
// 前者是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口
// 后者是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例
// 2、HandlerMethod及子类主要用于封装方法调用相关信息
// 简单点说我们可以通过这个类对象获得被调用方法的各种信息,如方法名、参数类型等
if(handler.getClass().isAssignableFrom(HandlerMethod.class)) {
//获得注解对象
Auth auth = ((HandlerMethod) handler).getMethodAnnotation(Auth.class);
Method method = ((HandlerMethod) handler).getMethod();
log.info("获取注解Auth的name值" + auth.name());
}
return true;
}
}
代码参考:
如上通过拦截器,获取方法注解的数值,然后可以进行你想要的业务逻辑处理,比如权限认证(验证每个方法是否拥有执行权限)。
这里是通过spirng拦截器的方式讲解了自定义注解,还有很多其他方式,大家可以google。