JavaWeb【自定义注解】

一。自定义注解(形体)

情形一: 单一注解

  定义

public @interface MyAnnotation {
    //定义注解属性:
    //属性类型 属性名() default 默认值;
    //String name() default "自定义名字";
    String name();
    int age() default 20;
    //注解属性类型:基本类型,String,Class,注解,枚举,和 前面几种类型的一维数组
    //Student student; error:The blank final field student may not have been initialized
}

  使用:

class Demo{
    //给注解赋值
    @MyAnnotation(name="段哥哥",sex="男")
    public void hello(){
        System.out.println("hello");
    }
}

情形二:注解的嵌套

  定义

public @interface MyAnnotation2 {
    String url() default "";
    MyAnnotation[] myAnnotations();
}

  使用

@MyAnnotation2(myAnnotations={@MyAnnotation(name="注解一",sex="女"),@MyAnnotation(name="注解二",sex="男")})
class Demo2{
    @MyAnnotation2(myAnnotations={@MyAnnotation(name="注解一",sex="女"),@MyAnnotation(name="注解二",sex="男")})
    public void hello(){
        System.out.println("hello");
    }
}

情形三:特殊的注解属性value

  定义

public @interface MyAnnotation3 {
    String name() default "name";
    String value() default "男";
}

  使用

class Demo3{
    @MyAnnotation3("who")
    public void hello(){}
}

  ps:当使用注解没有指定给哪个属性赋值时,默认是value属性,所以上面的who就赋值给了value属性。

情形四:数组类型的value

  定义

public @interface MyAnnotation3 {
    String[] value() default "";
}

  使用

class Demo3{
    //给数组指定一个值
    @MyAnnotation3("a")
    public void hello(){

    }
    //给数组指定二个值    { }的使用
    @MyAnnotation3({"a","b"})
    public void hello2(){

    }
}


  我们自定义的所有注解类型都是java.lang.Annotation接口的子类,既然子类,那么Annotation接口中的方法我们都可以使用


二。注解的反射(灵魂)

java.lang.reflect.AnnotatedElement 

  •   <T extends Annotation> T getAnnotation(Class<T> annotationClass):该方法获取指定Class类型的注解实例的引用
  •   Annotation[] getAnnotations():获取所有的注解,包含继承下来的
  •   Annotation[] getDeclaredAnnotations();获取自己直接使用的注解,不包含继承下来的
  •   boolean isAnnotaionPresent(Class<? extends Annotaion> annotionType):看看指定的注解在不在

  谁来调用这些方法,AnnotatedElement接口的实现类,有以下这几个AnnotatedElement的实现类:

  •   Class:表示一个类型
  •   Method:表示一个方法
  •   Field:表示一个字段
  •   Constructor:表示一个构造方法
  •   etc

类的三种状态

  注解也就是类,只要是类就有三种状态

一。SOURCE源代码(*.java)

  存在磁盘上

二。CLASS字节码(*.class)

  存在磁盘上

三。RUNTIME内存中的class

  从磁盘上加载到内存上。这就是类加载器所做的

  结论:在我们之前定义的注解,也就是类 处在CLASS字节码状态,存在于磁盘上

  验证上面的结论:

        Class class1=S.class;
        Method[] methods=class1.getMethods();
        for(Method m:methods){
            boolean flag=m.isAnnotationPresent(MyTest.class);
            System.out.println(m.getName()+"有没有"+flag);
        }

  控制台输出的都为false

注解的生命周期-元注解

  元注解:在注解上面定义的注解

  元注解的种类

  @Rentention

     作用;改变注解的存活范围

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

RetentionPolicy

     使用:在注解的定义上,当我们运行下面代码,控制台上就会看到true了

        Class class1=S.class;
        Method[] methods=class1.getMethods();
        for(Method m:methods){
            boolean flag=m.isAnnotationPresent(MyTest.class);
            System.out.println(m.getName()+"有没有"+flag);
        }

  但是单单使用了@Rentention只是改变了存活范围,该注解仅仅只能注解方法,要想在类上使用,我们需要在注解的位置上做限定

  @Target

     作用:注解应用的位置

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}

ElementType

  @Documented:应用了该注解的注解的类,对应的文档中是否显示注解

  @Inherited:被注解的注解的类 的子类,会自动注解子类

  

  结论:仅仅定义注解只是定义了形体,如果想要发挥作用,就是需要反射,而反射所依赖的一些东西,需要元注解去注解


三。注解的意义

  在开发中,通过一些xml配置来指挥程序的运行,

    缺点:开发不直观

    优点:避免硬编码

  注解是来替代xml作为配置用的

    优点:直观,开发简便,快速

    缺点:硬编码

时间: 2024-09-28 21:48:29

JavaWeb【自定义注解】的相关文章

Java自定义注解

自定义注解类编写的一些规则: 1. Annotation型定义为@interface, 所有的Annotation会自动继承Java.lang.Annotation这一接口,并且不能再去继承别的类或是接口. 2. 参数成员只能用public或默认(default)这两个访问权修饰 3. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String.Enum.Class.annotations等数据类型,以及这一些类

【java开发系列】—— 自定义注解(转)

之前在开发中,就总纳闷,为什么继承接口时,会出现@Override注解,有时候还会提示写注解@SuppressWarnings? 原来这是java特有的特性,注解! 那么什么是注解呢? 注解就是某种注解类型的一个实例,我们可以用它在某个类上进行标注,这样编译器在编译我们的文件时,会根据我们自己设定的方法来编译类. 注解都是什么呢?看下面这张图就明白了! 上面的图可以看出,注解大体上分为三种:标记注解,一般注解,元注解 这里面Override这个没测试出来,因为目前的Eclipse会自动帮我们排错

自定义注解框架的那些事

一.前言 距离上次更新已过一个半月,工作太忙也不是停更的理由.我这方面做得很不好,希望大家给予监督.首先会讲解[编译期资源注入],接着是[下拉刷新注入](通过注解来实现下拉刷新功能),最后打造一款[特色的注解框架]. 大家准备好公交卡了吗,开车了 - 二.什么是注解 每位童鞋对 注解 都有自己的理解,字面上的意思就是[额外的加入],在项目当中使用的注解的框架已经越来越多,如 : retrofit ,butterknife,androidannotations - 2017年Android百大框架

springmvc之自定义注解(annotation)

参考:日志处理 三:Filter+自定义注解实现 系统日志跟踪功能 1.项目结构 2.pom.xml,添加需要依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://mav

自定义标签-自定义注解

首先是4个自定义注解类StaticResourceType.java public enum StaticResourceType { LESS,CSS,JS} StaticResource.java @Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface StaticResource { StaticResourceType type(); String path(); Dependenc

使用Spring处理自定义注解

使用Spring处理自定义注解 本文只讲思想,不讲代码. 可能的两种方法 spring schema spring aop aspect 参考1 dubbo service 包名:com.alibaba.dubbo.config 参考2 spring mvc 包名:org.springframework.web.servlet.config 可以参考这两个的实现,利用schema添加自定义注解并处理自己的注解,注册搜索模块. 源码分析 通过schema添加配置解析如: 在 spring配置文件中

Spring自定义注解实现Controller获取想要的数据

最近看组内一个哥们写了一个HandlerAdapter,能自动获取Http请求里面的Cookie并组装成一个Model来直接使用.觉得很牛逼.因此自己做了一个,特来分享. 原理: 利用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter. 在DispatcherServlet里面定义了: private List<HandlerAdapter> handlerAdapters; 用于

自定义注解+拦截器实现权限控制

根据5.2中的讲解,当监控high priority queue的PDSP channel设定好后,那么与之对应的event就知道了(PDSP channel与event一一对应)(注意5.x讲的是中断的配置,并不是exception的配置,4.x讲的是exception) 中断event与ISR配置代码如下,目的是使event与ISR建立联系: /*Configure event*/ EventCombinerEventConfig( systemEvent,  (TEventCombiner

自定义注解的简单使用

    框架开发时不免会涉及到配置文件,如properties.xml以及txt等格式的文件.这里介绍框架中通过自定义注解的形式简化配置: 根据需求编写自定义注解中的属性(这里以JDBCConfig为例,这是一个注入数据库常用配置的注解类) @Target是java的元注解(即修饰注解的注解),这里的@Target({METHOD,TYPE})指可以修饰方法.描述类.接口(包括注解类型) 或enum声明. @Retention是java中的运行时注解,可以划分为三类   1.RetentionP