简介
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:自定义方法注解 @...
### 实现Java自定义注解拦截器 #### 概述 本文主要介绍如何在Spring Boot项目中使用自定义注解来实现对特定方法的拦截功能。具体场景为:当访问项目中的控制器方法时,需要进行“token验证”,但登录等特殊方法...
【Java项目拦截器分析与认识】 拦截器是Java开发中的一种常见技术,尤其在Spring MVC框架中,它扮演着重要角色。拦截器是一种动态拦截方法调用的机制,基于AOP(面向切面编程)思想,能够实现在指定方法调用前后...
在Spring Boot中注册拦截器,我们需要在配置类中使用`@EnableAspectJAutoProxy`开启AOP代理,并通过`@Bean`注解声明拦截器实例。然后,使用`@Around`注解定义切点,即拦截所有的JPA操作。 在实际开发中,为了使分库...
综上所述,Struts框架通过拦截器、扩展机制和Java注解提供了强大的功能,使得开发者能够构建结构清晰、易于维护的Web应用。理解并熟练运用这些知识点,对于提升Java Web开发的效率和质量有着重要意义。
在Java Web开发中,拦截器(Interceptor)是一个重要的概念,特别是在使用MVC框架如Struts2时。拦截器可以理解为一种预处理和后处理机制,它在请求到达控制器之前和离开控制器之后进行操作,例如日志记录、权限检查...
博客文章“struts2 以注解的形式实现拦截器”可能还详细介绍了如何在Struts2的配置中启用注解支持,以及如何通过注解配置拦截器的参数,以传递额外的信息给拦截器。 总之,使用注解在Struts2中实现拦截器提供了更...
在Java开发中,拦截器(Interceptor)是一种设计模式,它允许开发者在某个方法或运算执行前后插入自定义的行为。这通常用于实现日志记录、事务管理、权限验证等任务,而无需修改目标方法的源码。Java的拦截器机制...
在Java中,拦截器通常通过实现特定接口或者使用注解来定义。例如,Spring AOP中的`MethodInterceptor`接口和`@Around`注解,MyBatis中的`Interceptor`接口。下面我们将以Spring AOP为例,探讨如何创建和使用Java拦截...
本文将深入探讨Struts2拦截器的原理以及它与Java中的动态代理之间的联系。 首先,让我们了解Struts2拦截器的基本工作原理。拦截器在Action执行前后被调用,形成一个拦截器链。每当一个HTTP请求到达,Struts2的...
虽然在这个特定的例子中,`application.properties`可能没有直接与拦截器相关,但我们可以在这里配置一些全局属性,比如日志级别,这对于调试和监控拦截器的行为非常有用。例如: ```properties logging.level.org....
拦截器允许我们在请求被处理之前或之后执行自定义逻辑,比如身份验证、日志记录、权限检查等。在本文中,我们将专注于如何使用SpringBoot拦截器来处理404和500等错误。 首先,创建自定义拦截器类并实现`...
标题中的"ssh+aop+log4j+日志拦截器+注解"涉及到的是Java Web开发中的几个核心组件和技术,这些技术在构建大型、分布式的企业级应用时常常被使用。下面将详细介绍这些知识点: 1. SSH (Spring, Struts, Hibernate)...
然而,Struts2从2.1版本开始引入了拦截器注解,使得无需在配置文件中显式声明拦截器,就可以直接在Action类或方法上使用注解来应用拦截器。这种方式更简洁,减少了配置工作量,提高了代码可读性。 以下是几种常见的...
MyBatis是一个强大的Java持久层框架,它允许开发者将数据库操作与业务逻辑分离,通过XML或注解方式定义SQL语句。在某些场景下,我们可能需要对SQL进行动态修改或者实现分页功能,这时MyBatis的拦截器机制就显得尤为...
在Java Web开发中,拦截器(Interceptor)是一种重要的设计模式,它主要用于在请求处理之前、之后或处理过程中执行一些预定义的任务。拦截器通常被应用于框架中,如Spring MVC和Struts2,它们允许开发者在业务逻辑...
4. **创建拦截器**:在Spring中,我们可以通过实现`MethodInterceptor`接口或者使用`@Aspect`注解来创建拦截器。`MethodInterceptor`是AOP联盟的一部分,而`@Aspect`是AspectJ的注解,用于定义切面。 5. **配置拦截...
1. 拦截器的注册:拦截器需要在SpringMVC配置中进行注册,通过`<mvc:interceptors>`标签或者在Java配置中使用`addInterceptors()`方法添加到拦截器链中。每个拦截器都有`preHandle()`, `postHandle()` 和 `...
MyBatis中的拦截器(Interceptor)是基于Java的动态代理机制实现的,它可以拦截执行SQL的生命周期中的某些环节,如:预处理、结果映射等。在分页拦截器中,它会在执行查询之前对SQL进行修改,自动添加LIMIT和OFFSET...
MyBatis拦截器实现通用权限字段添加的方法 MyBatis拦截器是一种非常实用的技术,可以用来实现各种复杂的数据库操作。本文将详细介绍如何使用MyBatis拦截器来实现通用权限字段添加,达到灵活、可靠、可维护的数据库...