什么是注解?html
注解有什么做用?java
注解是怎么干活的?安全
如何自定义注解?框架
注解即元数据,一种描述数据的数据,能够说注解就是源代码的元数据ide
Annotation是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符函数
Annotation不能影响程序代码的运行,不管增长、删除注解,代码都始终如一的执行工具
元数据(metadata),数据的数据日志
元数据能够用来建立文档,跟踪代码的依赖性,执行编译时格式检查,代替已有的配置文件code
元数据以标签的形式存在于Java代码中,描述的信息是类型安全的(内部字段有明确类型)orm
Annotation类型定义了Annotation的名字、类型成员默认值,一个Annotation类型能够是一个特殊的java接口
使用XML描述元数据:XML是为了分离代码和配置而引入,但有时候咱们但愿使用一些和代码紧耦合的描述
Annotation出现以前,开发人员使用本身的方式定义元数据,如标记interfaces,注释,transient等
Annotation给了一个统一的标准规范,在许多框架中与XML结合使用,平衡二者的利弊
看源码@Override注解,你可能会疑惑,它什么都没有作,那它是如何检查在父类中有一个同名的函数
强调:Annotation仅仅是元数据,和业务逻辑无关
Annotation并不直接对程序的语法产生做用,可是会提供一些程序以外的数据或者信息,影响工具或者类库对程序的处理或者调用的方式,从而影响程序运行时的行为
元注解的做用就是负责注解其余注解,meta-annotation类型
@Target:用于描述注解的使用范围,即被描述的注解能够用在什么地方
ElementType.TYPE:用于描述类、接口或enum声明
ElementType.FIELD:用于描述实例变量,包括enum常量
ElementType.METHOD:用于描述方法
ElementType.PARAMETER:用于描述参数
ElementType.CONSTRUCTOR:用于描述构造器
ElementType.LOCAL_VARIABLE:用于描述局部变量
ElementType.ANNOTATION_TYPE:用于描述注解类型,另外一个注释
ElementType.PACKAGE:用于记录Java文件的package信息
ElementType.TYPE_PARAMETER:能够用在Type的声明前
ElementType.TYPE_USE:能够用在全部使用Type的地方
初始化对象:String myString = new @NotNull String();
使用 throws 表达式:public void validateValues() throws @Critical ValidationFailedException{ }
@Retention:表示须要在什么级别保存该注释信息,用于描述注解的生命周期,即被描述的注解在什么范围内有效
RetentionPolicy.SOURCE:在编译阶段丢弃,编译以后就再也不有任何意义,如@Override@SuppressWarnings
RetentionPolicy.CLASS:在类加载的时候丢弃,在字节码文件的处理中使用,注解默认使用这种方式
RetentionPolicy.RUNTIME:不会丢弃,运行时也保留该注解,可使用反射机制读取该注解信息,自定义注解一般使用这种方式
@Documented:注解是否包含在JavaDoc中
@Inherited:是一个标记注解,若是使用了该注解修饰的annotation注解的class,会被做用于该class的子类
自定义注解:@Todo
package com.adagio.demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义注解 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Todo { public enum Priority{LOW, MEDIUM, HIGH} public enum Status{STARTED, NOT, NOT_STARTED} String author() default "Yash"; Priority priority() default Priority.LOW; Status status() default Status.NOT_STARTED; }
若是注解只有一个属性,能够直接命名为"value",使用时无需在标明属性名
package com.adagio.demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Author { String value(); }
注解元素必须有肯定的值,能够在定义注解的默认值中指定,也能够在使用注解时指定
使用反射读取注解信息:BusinessLogic
package com.adagio.demo; import java.lang.reflect.Method; public class BusinessLogic { @Todo(priority = Todo.Priority.MEDIUM, author = "Yashwant", status = Todo.Status.STARTED) public void incompleteMethod(){ } @Author("Yashwant") public void someMethod(){ } public void readAnnotationInfo(){ Class<BusinessLogic> businessLogicClass = BusinessLogic.class; for(Method method : businessLogicClass.getMethods()){ Todo todoAnnotation = method.getAnnotation(Todo.class); if(todoAnnotation != null){ System.out.println("Method Name:" + method.getName()); System.out.println("Author:" + todoAnnotation.author()); System.out.println("Priority:" + todoAnnotation.priority()); System.out.println("Status:" + todoAnnotation.author()); } } } public static void main(String[] args) { System.out.println("开始读取》》》》"); BusinessLogic b = new BusinessLogic(); b.readAnnotationInfo(); System.out.println("读取结束》》》》"); } }
注解的功能很强大,Spring和Hibernate这些框架在日志和有效性中大量使用了注解功能
注解能够应用在使用标记接口的地方,不一样的是标记的接口用来定义完整的类,但你能够为单个方法定义注解,如将一个方法暴露为服务
servlet3.0引入的新注解,和servlet安全相关的注解:
HandlesTypes 该注解用来表示一组传递给ServletContainerInitializer的应用类
HttpConstraint 该注解表明全部HTTP方法的应用请求的安全约束
HttpMethodConstraint 指明不一样类型请求的安全约束
MultipartConfig 该注解标注在Serblet上,表处理请求MIME类型是multipart/form-data
ServletSecurity 该注解标注在Servlet继承类上,强制该HTTP协议请求遵循安全约束
WebFilter 该注解用来声明一个Servlet过滤器
WebInitParam 该注解用来声明Servlet或是过滤器中的初始化参数,一般配合@WebServlet或 @WebFilter使用
WebListener 该注解为Web应用程序上下文中不一样类型的事件声明监听器
WebServlet 该注解用来声明一个Servlet的配置
参考文档:
http://www.importnew.com/1029...
http://www.cnblogs.com/peida/...
http://www.cnblogs.com/peida/...
https://www.ibm.com/developer...