# 自定义注解

前提,了解注解是什么

# 1、注解

@Override 告诉服务器这个方法是覆盖父类的方法。

@WebServlet ("/test") 表示某个类是一个 Servlet,Web 容器就会识别这个注解,在运行的时候调用它。

@Controller ("/test") 表示某个类是一个控制器,告诉 Spring 框架该类是一个容器。

注释是给开发人员看的,不会影响程序的编译和运行。注解并不是给开发人员看的,是用于给程序看的,会影响程序的编译和运行。

# 1.2 @Target 指定注解针对的地方

# ElementType:

1、ElementType.TYPE: 针对类,接口

2、ElementType.FIELD: 针对字段 (成员变量)

3、ElementType.MONTHD: 针对方法

4、ElementType.PARAMETER: 针对方法参数

5、ElementType.CONSTRUCTOR: 针对构造器

6、ElementType.PACKAGE: 针对包

7、ElementType.ANNOTATION_TYPE: 针对注解

# 1.3 @Retention 指定注解的保留域

# RetentionPolicy:

1、RetentionPolicy.SOURCE: 源代码级别,由编译器处理,处理之后就不再保留

2、RetentionPolicy.CLASS: 字节码文件级别,注解信息保留到类对应的 class 文件中

3、RetentionPolicy.RUNTIME: JVM 级别,由 JVM 读取,运行时使用

PS:自定义注解要和反射一起使用

# 代码案例:

创建注解类

package com;
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 InitMethod
{
}

创建使用注解的类

package com;
public class InitDemo
{
    @InitMethod
    public void init()
    {
        System.out.println("init...");
    }
    public void test()
    {
    }
}

创建测试类编写注解的响应处理代码

package com;
import java.lang.reflect.Method;
public class Test
{
    public static void main(String[] args)
    {
        try
        {
            // 通过反射获取 Class 对象
            Class clazz = Class.forName("com.InitDemo");
            // 获取类上的注解方式
            Annotation annotaion = clazz.Annotation();
            if(annotaion != null)
            {
                //... 进行操作
            }
            // 获取当前 Class 对象的所有方法 (不包括父类)
            Method[] methods = clazz.getDeclaredMethods();
            if (methods != null)
            {
                for (Method method : methods)
                {
                    System.out.println(method);
                    // 判断方法是否有指定注解
                    boolean annotationPresent = method.isAnnotationPresent(InitMethod.class);
                    if (annotationPresent)
                    {
                        // 如果有就调用方法
                        method.invoke(clazz.getConstructor(null).newInstance(null), null);
                    }
                }
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
}

运行结果:

public void com.InitDemo.init()
init...
public void com.InitDemo.test()