简介
Annotation(注解),也叫元数据。一种代码级别的说明,是JDK5.0引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。 Annotion是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据。
注解基础
Annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息。Annotation不影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行,但可以通过Java反射工具对Annotation进行访问和处理。
根据注解使用方法和用途,可以将Annotation分为三类:
JDK内置系统注解
注解的语法比较简单,除了@符号的使用外,他基本与Java固有的语法一致,JavaSE中内置三个标准注解,定义在java.lang中:
- @Override:用于修饰此方法覆盖了父类的方法;
- @Deprecated:用于修饰已经过时的方法,可能在未来版本废弃;
- @SuppressWarnnings:用于通知java编译器禁止特定的编译警告。
元注解
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。
- @Documented
- @Target
- @Retention
- @Inherited
这些类型和它们所支持的类在java.lang.annotation包中可以找到。
Documented
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceDocumented{}
@Documented可以用于javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
Target注解
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceTarget{ElementType[] value();}
@Target说明了Annotation所修饰的对象范围,它所支持的范围在ElementType枚举中描述。
publicenumElementType{
TYPE,/** Class, interface (including annotation type), or enum declaration */
FIELD,/** Field declaration (includes enum constants) */
METHOD,/** Method declaration */
PARAMETER,/** Parameter declaration */
CONSTRUCTOR,/** Constructor declaration */
LOCAL_VARIABLE,/** Local variable declaration */
ANNOTATION_TYPE,/** Annotation type declaration */
PACKAGE /** Package declaration */}
Retention注解
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceRetention{RetentionPolicy value();}
@Retention定义了该Annotation被保留的时间长短。
publicenumRetentionPolicy{
SOURCE,
CLASS,
RUNTIME
}
- SOURCE:被编译器丢弃,仅源文件保留
- CLASS:编译器记录注解在class文件里面,运行时被虚拟机丢弃,默认。
- RUNTIME:编译器记录注解在class文件里面,运行时虚拟机会保留,可通过反射读取。
Inherited注解
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public@interfaceInherited{}
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口。
定义注解格式:
public@interfaceAnnotationName{body...}
注解的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称。 注解参数的可支持数据类型:基本数据类型,String,CLass,enum,Annotation及前面类型的数组。 可以通过default来声明参数的默认值。
仅仅定义注解还不够,重要的是要通过注解处理器来处理自定义的注解,Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器。
Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素。
publicinterfaceAnnotatedElement{/** 判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false. */boolean isAnnotationPresent(Class<?extendsAnnotation> annotationClass);/** 返回存在的指定类型的注解,否则返回null */<T extendsAnnotation> T getAnnotation(Class<T> annotationClass);/** 返回所有注解 */Annotation[] getAnnotations();/** 返回直接存在于此元素上的所有注释。 */Annotation[] getDeclaredAnnotations();}
定义注解
定义Before注解,用于在类或者方法时,可在运行时读取。可配置继承Interceptor接口的Class数组。
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;@Inherited@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.METHOD})public@interfaceBefore{Class<?extendsInterceptor>[] value();}
定义拦截器
拦截器接口,为了方便模拟,方法的参数为Object对象
publicinterfaceInterceptor{void intercept(Object obj);}
定义了三个实现Interceptor接口的类,分别为CommonInterceptor,AuthorityInterceptor和CacheInterceptor。
publicclassCommonInterceptorimplementsInterceptor{@Overridepublicvoid intercept(Object obj){System.out.println("Common Interceptor invoke ... ");}}publicclassAuthorityInterceptorimplementsInterceptor{@Overridepublicvoid intercept(Object obj){System.out.println("Authority Interceptor invoke ... ");}}publicclassCacheInterceptorimplementsInterceptor{@Overridepublicvoid intercept(Object obj){System.out.println("Cache Interceptor invoke ... ");}}
定义Action控制类
对Action类添加了注解和方法上添加了0到多个拦截器。
@Before(CommonInterceptor.class)publicclassAction{@Before(AuthorityInterceptor.class)publicvoid save(){System.out.println("foo");}@Before({CacheInterceptor.class,AuthorityInterceptor.class})publicvoid view(){System.out.println("view");}publicvoid list(){System.out.println("list");}}
定义注解处理器
方法上面的拦截器集合有方法上自定义的拦截器和类上定义的拦截器所组成。 步骤:(1) 取得Class上的Before注解,获得此Class上配置的拦截器;(2) 对Class的每个方法获得Method对象,并获得在此Method上配置的拦截器;(3) 将上面两步获得的拦截器合并,对应方法上所配置的拦截器集合。(4) 配置路由和拦截器的关联关系,路由简单的由类名和方法名组成。
import java.util.HashMap;import java.util.Map;import java.lang.reflect.Method;publicclassInterceptorParse{privatestaticfinalInterceptor[] NULL_INTERCEPTOR_ARRAY =newInterceptor[0];publicMap<String,Interceptor[]> parse(Class klass){Map<String,Interceptor[]> result =newHashMap<String,Interceptor[]>();String className = klass.getName();Before classBefore =(Before)klass.getAnnotation(Before.class);Interceptor[] classInterceptors = getInterceptors(classBefore);//Method[] methods = klass.getMethods();Method[] methods = klass.getDeclaredMethods();for(Method method : methods){String methodName = method.getName();Before methodBefore =(Before)method.getAnnotation(Before.class);Interceptor[] methodInterceptors = getInterceptors(methodBefore);Interceptor[] availableInterceptors = combineInterceptors(classInterceptors, methodInterceptors);
result.put(className+"/"+methodName, availableInterceptors);}return result;}privateInterceptor[] getInterceptors(Before beforeAnnotation){if(beforeAnnotation ==null)return NULL_INTERCEPTOR_ARRAY;Interceptor[] result =null;Class<Interceptor>[] interceptorClasses =(Class<Interceptor>[]) beforeAnnotation.value();if(interceptorClasses !=null&& interceptorClasses.length >0){
result =newInterceptor[interceptorClasses.length];for(int i=0; i<result.length; i++){try{
result[i]=(Interceptor)interceptorClasses[i].newInstance();}catch(Exception e){thrownewRuntimeException(e);}}}return(result !=null)?result:NULL_INTERCEPTOR_ARRAY;}privateInterceptor[] combineInterceptors(Interceptor[] first,Interceptor[] second){if(first.length ==0)return second;if(second.length ==0)return first;Interceptor[] result =newInterceptor[first.length + second.length];int idx =0;for(Interceptor interceptor: first){
result[idx++]= interceptor;}for(Interceptor interceptor: second){
result[idx++]= interceptor;}return result;}publicstaticvoid main(String[] args){InterceptorParse interceptorParse =newInterceptorParse();Map<String,Interceptor[]> map = interceptorParse.parse(Action.class);for(Map.Entry<String,Interceptor[]> entry : map.entrySet()){System.out.println("path: "+ entry.getKey());Interceptor[] interceptors = entry.getValue();for(Interceptor interceptor: interceptors){System.out.println("Interceptor:"+ interceptor.getClass().getName());
interceptor.intercept(null);}System.out.println();}}}
运行结果
path:Action/list
Interceptor:CommonInterceptorCommonInterceptor invoke ...
path:Action/view
Interceptor:CommonInterceptorCommonInterceptor invoke ...Interceptor:CacheInterceptorCacheInterceptor invoke ...Interceptor:AuthorityInterceptorAuthorityInterceptor invoke ...
path:Action/save
Interceptor:CommonInterceptorCommonInterceptor invoke ...Interceptor:AuthorityInterceptorAuthorityInterceptor invoke ...
相关推荐
java 元注解+拦截器实现自定义注解 @CmwAutoWired:自定义依赖注入 注意:注入的接口和实现类需要在同一包名下,注解的是类则无限制 @FieldAnnotation:自定义属性注解 @MethodAnnotation:自定义方法注解 @...
内容:拦截器的使用很简单,定义一个自己的拦截器,向配置中添加一下就可以使用。...oTokenInterceptor.java 自定义拦截器 oInterceptorConfig.java 添加拦截器进入项目 oNoNeedToken.java 自定义注解
springboot spring aop 拦截器 注解方式实现脱敏(涉及到:pom.xml -->application.properties --->启动类-->拦截器)
针对spring boot 集成jpa sql操作进行自定义分库分表逻辑
自定义拦截器的实现以及拦截器的详细配置,配置文件里面有特别详细的注释,希望对刚接触拦截器的同学有帮助
自己学习springmvc个人写的注解事例,其中包括各种传参方式,其中还写了一个拦截器,文件上传功能,希望对学习springmvc的新手有所帮助。
给你源码(很详细的注释),看不看无所谓(建议看【技多不压身不是】),反正让你会用(了解原理更好)
NULL 博文链接:https://zhouxianglh.iteye.com/blog/523783
防止接口重复提交实现原理 1.定义注解,加在接口方法上 2.自定义实现拦截器 拦截校验有此注解的方法,判断距离上次提交时间间隔
j2ee中拦截器+切入点+正则切入点+代理中的一些例子,applicationContext.xml中有详细的注释
springboot自定义注解的demo;通过本案例实现了通过...通过拦截器获取指定方法上的自定义的注解,然后判断当前的接口需不要权限校验;然后通过对应的访问去处理;demo里面的代码简单;文档齐全,初学者秒懂.本文一篇文章搞定
SpringBoot-自定义注解AOP实现及拦截器示例代码
springBoot-java敏感词语过滤类
网上很多人想使用注解拦截spring mvc action中的一个方法,实现方法很多,一般是通过在拦截器中分析url路径来实现, 使用自定义注解的方式来标注要拦截的 action 中的某个方法, 没有很好的解决方法, 如果通过借助spring...
SpringBoot AOP各种注解、自定义注解、鉴权使用案例SpringBoot AOP各种注解、自定义注解、鉴权使用案例SpringBoot AOP各种注解、自定义注解、鉴权使用案例
主要介绍了java MyBatis拦截器Inteceptor详细介绍的相关资料,需要的朋友可以参考下
特性 注解简单: 遵循大家的命名习惯,@Body、@Query、@Var等注解见名之意。 无侵入: 接口不需要继承。...拦截器可满足大部分业务需求,如:计算请求耗时,动态添加公共请求头,返回错误统一处理等等。
主要介绍了详解利用SpringMVC拦截器控制Controller返回值,通过定义一个StringResult注解,在访问方法的时候返回StringResult中的内容,有兴趣的可以了解一下。
springboot工程通过自定义response注解、java反射机制、自定义java拦截器、自定义功能类实现WebMvcConfigurer接口等功能,实现自定义规范化返回数据结构。
拦截器和过滤器有什么区别?程序中是先执行拦截器还是过滤器?请描述Mybatis结果集中 ResultMap 和ResultType的区别。Java中 @PostConstruct和@PreDestroy注解有什么作用?编写Webservice接口服务端(框架)有几种...