精华内容
下载资源
问答
  • java 注解生命周期

    千次阅读 2019-11-11 17:06:42
    对注解概念不了解的可以先看这个:Java注解基础概念总结 前面有提到注解按生命周期来划分可分为3类: 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;2、...

    对注解概念不了解的可以先看这个:Java注解基础概念总结
    前面有提到注解按生命周期来划分可分为3类:
    1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
    这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
    那怎么来选择合适的注解生命周期呢?
    首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife 和 mapstruct 等),就用 CLASS注解;如果只是做一些检查性的操作,比如** @Override**和 @SuppressWarnings,则可选用 SOURCE 注解。
    下面来介绍下运行时注解的简单运用。
    获取注解
    你需要通过反射来获取运行时注解,可以从 Package、Class、Field、Method...上面获取,基本方法都一样,几个常见的方法如下:

    /** 
     * 获取指定类型的注解 
     */  
    public <A extends Annotation> A getAnnotation(Class<A> annotationType);  
      
    /** 
     * 获取所有注解,如果有的话 
     */  
    public Annotation[] getAnnotations();  
      
    /** 
     * 获取所有注解,忽略继承的注解 
     */  
    public Annotation[] getDeclaredAnnotations();  
      
    /** 
     * 指定注解是否存在该元素上,如果有则返回true,否则false 
     */  
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType);  
      
    /** 
     * 获取Method中参数的所有注解 
     */  
    public Annotation[][] getParameterAnnotations(); 
    

    要使用这些函数必须先通过反射获取到对应的元素:Class、Field、Method 等。
    自定义注解来看下自定义注解的简单使用方式,这里先定义3个运行时注解:

    // 适用类、接口(包括注解类型)或枚举  
    @Retention(RetentionPolicy.RUNTIME)  
    @Target(ElementType.TYPE)  
    public @interface ClassInfo {  
        String value();  
    }  
    // 适用field属性,也包括enum常量  
    @Retention(RetentionPolicy.RUNTIME)  
    @Target(ElementType.FIELD)  
    public @interface FieldInfo {  
        int[] value();  
    }  
    // 适用方法  
    @Retention(RetentionPolicy.RUNTIME)  
    @Target(ElementType.METHOD)  
    public @interface MethodInfo {  
        String name() default "long";  
        String data();  
        int age() default 27;  
    }
    

    这3个注解分别适用于不同的元素,并都带有不同的属性,在使用注解是需要设置这些属性值。
    再定义一个测试类来使用这些注解:

    /** 
     * 测试运行时注解 
     */  
    @ClassInfo("Test Class")  
    public class TestRuntimeAnnotation {  
      
        @FieldInfo(value = {1, 2})  
        public String fieldInfo = "FiledInfo";  
      
        @FieldInfo(value = {10086})  
        public int i = 100;  
      
        @MethodInfo(name = "BlueBird", data = "Big")  
        public static String getMethodInfo() {  
            return TestRuntimeAnnotation.class.getSimpleName();  
        }  
    }  
    

    使用还是很简单的,最后来看怎么在代码中获取注解信息:

    /** 
     * 测试运行时注解 
     */  
    private void _testRuntimeAnnotation() {  
        StringBuffer sb = new StringBuffer();  
        Class<?> cls = TestRuntimeAnnotation.class;  
        Constructor<?>[] constructors = cls.getConstructors();  
        // 获取指定类型的注解  
        sb.append("Class注解:").append("\n");  
        ClassInfo classInfo = cls.getAnnotation(ClassInfo.class);  
        if (classInfo != null) {  
            sb.append(Modifier.toString(cls.getModifiers())).append(" ")  
                    .append(cls.getSimpleName()).append("\n");  
            sb.append("注解值: ").append(classInfo.value()).append("\n\n");  
        }  
      
        sb.append("Field注解:").append("\n");  
        Field[] fields = cls.getDeclaredFields();  
        for (Field field : fields) {  
            FieldInfo fieldInfo = field.getAnnotation(FieldInfo.class);  
            if (fieldInfo != null) {  
                sb.append(Modifier.toString(field.getModifiers())).append(" ")  
                        .append(field.getType().getSimpleName()).append(" ")  
                        .append(field.getName()).append("\n");  
                sb.append("注解值: ").append(Arrays.toString(fieldInfo.value())).append("\n\n");  
            }  
        }  
      
        sb.append("Method注解:").append("\n");  
        Method[] methods = cls.getDeclaredMethods();  
        for (Method method : methods) {  
            MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);  
            if (methodInfo != null) {  
                sb.append(Modifier.toString(method.getModifiers())).append(" ")  
                        .append(method.getReturnType().getSimpleName()).append(" ")  
                        .append(method.getName()).append("\n");  
                sb.append("注解值: ").append("\n");  
                sb.append("name: ").append(methodInfo.name()).append("\n");  
                sb.append("data: ").append(methodInfo.data()).append("\n");  
                sb.append("age: ").append(methodInfo.age()).append("\n");  
            }  
        }  
      
        System.out.print(sb.toString());  
    }  


     


     

    展开全文
  • Spring注解 生命周期初始化和销毁调用时机自定义初始化和销毁的方式@Bean指定初始化和销毁方法initializingBean和DisposableBean接口@PostConstruct 和@PreDestroyBeanPostProcessor 后置处理器BeanPostProcessor...

    Spring注解 生命周期

    初始化和销毁调用时机

    自定义初始化和销毁的方式

    @Bean指定初始化和销毁方法

    initializingBean和DisposableBean接口

    @PostConstruct 和@PreDestroy

    BeanPostProcessor 后置处理器

    BeanPostProcessor原理

    Spring底层对BeanPostProcessor的使用

    bean的生命周期:bean创建–>初始化–>销毁的过程

    在Spring中由容器管理bean的生命周期,我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的是或来调用我们自己定义的初始化和销毁方法

    初始化和销毁调用时机

    生命周期:

    构造(对象创建)

    单实例:在容器启动的时候创建

    多实例:在每次获取的时候创建

    BeanPostProcessor.postProcessBeforeInitialization

    初始化

    对象创建完成并赋值好,调用初始化方法

    BeanPostProcessor.postProcessAfterInitialization

    销毁

    单实例:容器关闭的时候

    多实例:容器不会管理这个bean,容器不会调用销毁方法

    f286616a58e5a067582045c316b58bb0.png

    自定义初始化和销毁方法的方式:

    @Bean指定初始化和销毁方法

    实现initializingBean和DisposableBean接口

    @PostConstruct 和@PreDestroy

    BeanPostProcessor 后置处理器

    在初始化前后

    自定义初始化和销毁的方式

    @Bean指定初始化和销毁方法

    第一种方式是通过@Bean指定初始化和销毁方法

    @Bean(initMethod = "init",destroyMethod = "destroy")

    @Bean 有两个属性:

    initMethod = “init” 指定初始化方法名为init(在要创建的类中的方法)

    destroyMethod = “destroy” 指定销毁方法名为destroy

    这两个属性就等价于xml里Bean标签的init-method属性和destroy-method属性

    fd8949872c46bab7812df34f413f387d.png

    349a4990793984d07277a3b95bd0abe9.png

    单实例情况的输出:

    f1aebebb2319591adf9bb1a52884158c.png

    initializingBean和DisposableBean接口

    我们可以通过让Bean实现initializingBean接口定义初始化,的afterPropertiesSet()方法会在bean创建完成并属性赋值好后调用

    让Bean实现DisposableBean接口定义销毁,DisposableBean接口的destroy()方法会在容器关闭的时候调用

    109e5dbd0e1e9dc3fd92f3b066702bb9.png

    @PostConstruct 和@PreDestroy

    JSR250规范定义了两个注解:

    这两个注解都是标在方法上的

    @PostConstruct 在bean创建完成并且属性赋值完成,来执行初始化方法

    @PreDestroy 在容器销毁bean之前 会调用这个注解标注的方法

    cf031e6f75be385fd680aac74e9bd5d2.png

    BeanPostProcessor 后置处理器

    在bean初始化前后进行一些处理工作

    postProcessBeforeInitialization在bean创建后但初始化之前(例如initializingBean的afterPropertiesSet方法调用、initMethod指定的方法调用)

    postProcessAfterInitialization bean初始化之后调用

    这两个方法的参数:

    bean就是容器中已经创建的对象(返回也返回这个对象)

    beanName就是对象的名字

    26182f2ca86a2dffa0f1639c9577cd5b.png

    BeanPostProcessor原理

    populateBean()//1. 给属性赋值

    {

    //2. 后置处理器 调用PostProcessorsBeforeInitialization()方法

    applyBeanPostProcessorsBeforeInitialization

    //3. 调用自定义初始化方法

    invokeInitMethods

    //4. 后置处理器 调用PostProcessorsAfterInitialization()方法

    applyBeanPostProcessorsAfterInitialization

    }

    在doCreateBean方法中

    我们可以看到是先调populateBean()方法对bean的属性进行赋值,然后再调用initializeBean()方法

    62819df23f3286733d21a1d70a6a8aeb.png

    initializeBean()方法中

    1d652a95146a5427c588b0a693b7c79c.png

    applyBeanPostProcessorsBeforeInitialization()方法

    这个方法就是把所有的后置处理器都拿出来,然后调用每个的postProcessBeforeInitialization方法,如果有一个为null,就返回(后面的后置处理器就不调用了)

    44c37ab478ae59ce720274e6bd7dc378.png

    Spring底层对BeanPostProcessor的使用

    展开全文
  • 前言一直都在使用注解,但是一直都没有用的很明白,后来被逼的发现不搞明白真的就...注解说明Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。为我们在代码中添加信息提供了一种形式...

    前言

    一直都在使用注解,但是一直都没有用的很明白,后来被逼的发现不搞明白真的就没有办法愉快的写代码了,所以,这篇《Java中的注解学习笔记》就呼之欲出了,在我的各种不情愿之下,在我浪费了好几个小时的情况下,总算对这个注解有了一个入门的学习,对付一般的注解问题是足够了。

    注解说明

    Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java虚拟机可以保留注解内容,在运行时可以获取到注解内容。

    内置注解

    Java定义了一套注解,共有7个,3个在java.lang中,剩下4个在java.lang.annotation中。

    作用在代码的注解是:

    @Override – 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

    @Deprecated – 标记过时方法。如果使用该方法,会报编译警告。

    @SuppressWarnings – 指示编译器去忽略注解中声明的警告。

    作用在其他注解的注解(或者说元注解)是:

    @Retention – 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

    @Documented – 标记这些注解是否包含在用户文档中。

    @Target – 标记这个注解应该是哪种Java成员。

    @Inherited – 标记这个注解是继承于哪个注解类(默认注解并没有继承于任何子类)

    从Java 7开始,额外添加了3个注解:

    @SafeVarargs – Java 7开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

    @FunctionalInterface – Java 8开始支持,标识一个匿名函数或函数式接口。

    @Repeatable – Java 8开始支持,标识某注解可以在同一个声明上使用多次。

    元注解

    元注解就是上面说到的作用在其他注解上的注解。

    @Retention:表明该注解的生命周期

    生命周期类型

    描述

    RetentionPolicy.SOURCE

    标记的注释仅保留在源级别中,并由编译器忽略。

    RetentionPolicy.CLASS

    标记的注释在编译时由编译器保留,但Java虚拟机(JVM)会忽略。

    RetentionPolicy.RUNTIME

    标记的注释由JVM保留,因此运行时环境可以使用它。

    @Documented:表明该注解标记的元素可以被Javadoc或类似的工具文档化

    @Target: 表明该注解可以应用的java元素类型

    Target类型

    描述

    ElementType.TYPE

    可以应用于类的任何元素。

    ElementType.FIELD

    可以应用于字段或属性。

    ElementType.METHOD

    可以应用于方法级注释。

    ElementType.PARAMETER

    可以应用于方法的参数。

    ElementType.CONSTRUCTOR

    可以应用于构造函数。

    ElementType.LOCAL_VARIABLE

    可以应用于局部变量。

    ElementType.ANNOTATION_TYPE

    可以应用于注释类型。

    ElementType.PACKAGE

    可以应用于包声明。

    ElementType.TYPE_PARAMETER

    1.8版本新增,应用于类型变量

    ElementType.TYPE_USE

    1.8版本新增,应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型)

    @Inherited:表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解

    @Repeatable:Java SE 8中引入的,@Repeatable注释表明标记的注释可以多次应用于相同的声明或类型使用(即可以重复在同一个类、方法、属性等上使用)。

    自定义注解

    其实说了这么多,都是一些总结性的知识点,我敢说到现在,大家还是对注解是云里雾里的。想要更好的认识注解,只有我们自己定义一个注解,来实现一个我们的注解,通过实现一个我们自己的注解来熟悉注解的工作流程。

    Java中自定义注解和创建一个接口相似,声明一个注解要用到以下东西:

    修饰符:访问修饰符必须为public,不写默认为pubic;

    关键字:关键字为@interface;

    注解名称:注解名称为自定义注解的名称,使用时还会用到;

    注解类型元素:注解类型元素是注解中内容,可以理解成自定义接口的实现部分。

    同时需要注意以下事项:

    注解方法不能有参数;

    注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组;

    注解方法可以包含默认值;

    注解可以包含与其绑定的元注解,元注解为注解提供信息。

    规则知道了,下面我来编码实现一个自定义的注解。比如我们在实现一个自定义的ORM框架的时候,都会通过注解来实现数据表名与JAVA类的映射,表字段与JAVA类字段的映射关系,下面就来简单实现这个功能。

    定义Table注解:

    package com.jellythink.annotation;

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(value={ElementType.TYPE})

    @Retention(RetentionPolicy.RUNTIME)

    public @interface Table {

    String value();

    }

    定义字段注解:

    package com.jellythink.annotation;

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(value={ElementType.FIELD})

    @Retention(RetentionPolicy.RUNTIME)

    public @interface FieldMapping {

    String name();

    String type();

    int length();

    }

    应用注解:

    package com.jellythink;

    import com.jellythink.annotation.FieldMapping;

    import com.jellythink.annotation.Table;

    @Table("tb_student")

    public class Student {

    @FieldMapping(name = "id", type = "int", length = 10)

    private int id;

    @FieldMapping(name = "name", type = "varchar", length = 6)

    private String stuName;

    @FieldMapping(name = "age", type="int", length = 4)

    private String stuAge;

    // 省略getter and setter

    }

    读取注解信息:

    package com.jellythink;

    import com.jellythink.annotation.Table;

    import com.jellythink.annotation.FieldMapping;

    import java.lang.reflect.Field;

    public class Main {

    public static void main(String[] args) {

    try {

    Class clazz = Class.forName("com.jellythink.Student");

    // 查询类上的注解

    Table tbStudent = (Table)clazz.getAnnotation(Table.class);

    System.out.println(tbStudent.value());

    // 查询属性上的注解

    Field stuId = clazz.getDeclaredField("id");

    FieldMapping fieldStuId = stuId.getAnnotation(FieldMapping.class);

    System.out.println(fieldStuId.name() + "--" + fieldStuId.type() + "--" + fieldStuId.length());

    Field stuName = clazz.getDeclaredField("stuName");

    FieldMapping fieldStuName =

    stuName.getAnnotation(FieldMapping.class);

    System.out.println(fieldStuName.name() + "--" + fieldStuName.type() + "--" + fieldStuName.length());

    Field stuAge = clazz.getDeclaredField("stuAge");

    FieldMapping fieldStuAge =

    stuName.getAnnotation(FieldMapping.class);

    System.out.println(fieldStuAge.name() + "--" + fieldStuAge.type() + "--" + fieldStuAge.length());

    // 通过上面查询到的数据拼接成SQL语句

    String name = "果冻";

    String sql =

    "select * from " + tbStudent.value() + " where " + fieldStuName.name() + " = '" + name + "'";

    System.out.println("SQL=" + sql);

    } catch (Exception e) {

    // Handle the exception

    }

    }

    }

    通过上面的代码,有木有感受到自定义注解还是非常简单的;同时有没有感觉到注解这个功能是非常强大的。

    总结

    总的来说,注解这个功能很强大,但是使用起来确是非常简单的,这就是牛叉东西的特点,好用又让人不感觉到复杂。以后再遇到注解东西,内心就不再犯怵,不再迷茫了。

    果冻想,认真玩技术的地方。

    2020年10月20日,于内蒙古呼和浩特。

    展开全文
  • 注解的概念java注解:比较官方的说法:从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的...

    注解的概念

    java注解:

    比较官方的说法:

    从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

    注解,可以看作是对 一个 类/方法 的一个扩展的模版,每个 类/方法 按照注解类中的规则,来为 类/方法 注解不同的参数,在用到的地方可以得到不同的 类/方法 中注解的各种参数与值。

    说说我的理解

    注解就是Annotation,相信不少人也和我之前一样以为和注释一样,是一段辅助性的文字,其实注解不是这样的。注解与注释的区别在于,注解可以实现程序的某些功能。

    注解是不会影响java程序的运行,不会干扰程序代码的运行。通俗来讲,注解就像一个标签,初学者需要知道他就像一个功能标签,能实现一些功能就行了!入门了再慢慢深入理解。

    看下面的例子你就能更好的理解注解了。

    注解的类别

    (1)java语言提供的注解

    (2)元注解

    (3)其他注解

    java语言提供的注解

    1.Override

    学过java你就知道,你肯定见过这种

    @Override

    public Object clone() throws CloneNotSupportedException {}

    没错,@Override就是一个java提供的注解。当你要重写父类的方法是需要用到这个注解。

    2.@Deprecated

    这个注解你能看到的时间比较少,但是你应该见过类似的,编译一个java程序时,编译器可能会提示你你使用了一个过时的方法(idea会),或者过时的类,过时的成员变量。

    3.@SuppressWarnings

    这个注解的意思是:阻止编译器的警告,上一个注解说到@Deprecated会提示你使用过时方法等的一个警告,当你使用了这个注解之后就不会有这种提示了!这个注解需要一个参数,参数都是提前设计好了的。

    参数如下

    (1)deprecation 使用了过时的类或方法的警告

    (2)unchecked 执行了未检查的转换时的警告,如使用集合时未指定泛型

    (3)fallthrough :当在switch语句使用时发生case穿透

    (4)path 在类路径,源文件路径等中有不存在路径的警告

    (5)serial 当在可序列化的类上缺少serialVersionUID定义时的警告

    (6)finally 任何finally子句不能完成时的警告

    (7)all 关于以上所有情况的警告

    元注解

    所谓元注解就是注解的注解,虽然说这些注解也是java语言提供的,但是他不同于上面说的哪几种注解,上面的几种注解也是由

    元注解组成的。他们的源代码里面包含了元注解。

    元注解有哪些呢?

    - @Target:注解的作用目标

    - @Retention:注解的生命周期

    - @Documented:注解是否应当被包含在 JavaDoc 文档中

    - @Inherited:是否允许子类继承该注解

    这4个值java8之前的元注解,在java8又新增了一个

    @Repeatable 元注解,表示被修饰的注解可以用在同一个声明式或者类型加上多个相同的注解(包含不同的属性值)

    我们详细说一下这些注解都是什么意思

    1.@Target 注解的作用目标

    具体的作用目标有以下几个

    - ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上

    - ElementType.FIELD:允许作用在属性字段上

    - ElementType.METHOD:允许作用在方法上

    - ElementType.PARAMETER:允许作用在方法参数上

    - ElementType.CONSTRUCTOR:允许作用在构造器上

    - ElementType.LOCAL_VARIABLE:允许作用在局部变量上

    - ElementType.ANNOTATION_TYPE:允许作用在注解上

    - ElementType.PACKAGE:允许作用在包上

    以上都是这个注解的参数

    可能有人会问作用目标是什么?就是说我声明的这个注解可以用在那个地方,比如说@Override,是不是只能用在重写的方法上面。如果你学了springboot的话,里面的很多注解都是可以使用在类上面也可以使用在方法上面。

    2.@Retention 注解的生命周期

    什么意思?注解本身是不会影响正常逻辑程序的运行的,然后这个注解的生命周期指的是我声明的这个注解会保留到什么阶段,具体的参数如下:

    - RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件,会被编译器丢弃

    - RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件,会被java虚拟机丢弃

    - RetentionPolicy.RUNTIME:永久保存,可以反射获取到对应的注解

    3.@Documented 注解是否应当被包含在 JavaDoc 文档中

    这个倒没有什么好说的,就是标注被修饰这个注解包含在JavaDoc文档中。

    4.@Inherited 是否允许子类继承该注解

    简单点说,子类继承父类时,如果父类的注解有@Inherited标识的注解,子类继承过来的时候也会自动继承@Inherited标识的注解。

    但是在接口继承的时候,子类不会继承任何@Inherited标识的注解。

    5.@Repeatable

    在需要对同一种注解多次使用时,往往需要借助@Repeatable。比如说,现在有一篇文章,这篇文章需要添加多个标签,这些标签就相当于注解,但是这个标签只是内容不同,这时候就需要使用到这个注解了。

    其他注解

    所谓的其他注解就是第三方注解,比如说很火的springboot,它提供了很多的注解,可以替代一些配置文件,告诉这个框架有这个注解是需要提供哪些功能。比如说@Controller,@RequestMapping,@Service等。

    注解用法

    讲了半天,可能你还是一脸懵逼,你只讲概念,怎么用?

    下面就来介绍这个注解怎么用,主要是讲解注解的声明用法。

    1.注解声明

    public @interface Entity {

    }

    这个和声明接口很类似,只是在前面多了一个@

    具体怎么用,我们用一个例子来讲解

    @Target(ElementType.TYPE)//允许声明的注解修饰在接口,类,枚举上面

    @Retention(RetentionPolicy.RUNTIME)//代码运行期间一直保存注解,可以通过反射获取

    public @interface Entity {

    //表名,注解的参数,默认为空

    public String tableName() default "";

    //中文名称

    public String cnName() default "";

    }

    解释一下注解的参数声明

    第一个参数定义参数为String类型,设置default 默认值,表示这个不是必须的,在使用注解的时候没有填写这个参数不会报错,他会使用默认值。

    声明好注解之后,我们将这些注解运用到一个实体类上面。

    再来一个声明的作用在属性上面的注解。

    @Target(ElementType.FIELD)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface Column {

    //属性的名称

    public String fieldName() default "";

    //属性的属性中文名称

    public String fieldCnName() default "";

    //属性的类型

    public String Type() default "String";

    }

    然后我们将这两个注解运用到实体类Student上面。

    @Entity(tableName = "student",cnName = "学生表")

    public class Student {

    @Column(fieldCnName = "姓名",fieldName ="name")

    private String name;

    @Column(fieldCnName = "年龄",fieldName = "age",Type = "Integer")

    private Integer age;

    @Column(fieldCnName = "性别",fieldName = "sex")

    private String sex;

    }

    set,get方法没有贴上来。

    具体的用法就是这样了。然后我们说说注解与反射的关系,怎么用反射获取注解。

    通过反射获取注解

    不会反射的请看上一篇文章,8000字为你讲懂反射,然后再回来看这篇注解的文章。

    上代码直接

    //获取Class类

    Class clazz = Student.class;

    //获取类上面的注解

    Entity entity = (Entity) clazz.getAnnotation(Entity.class);

    System.out.println(entity.cnName()+entity.tableName());

    //获取所有该类声明的属性

    Field fields[] = clazz.getDeclaredFields();

    for (Field field:fields){

    //获取对应属性上面的注解

    Column column = field.getAnnotation(Column.class);

    System.out.println(column.fieldCnName());

    }

    这个运行结果是

    学生表student

    姓名

    年龄

    性别

    很简单是不是。懂了吗?懂了的话关注走一波?精彩美文每天为你推送,喜欢手机看文章的还可以(wx search 全栈学习笔记)!

    反射注解一起使用拼写SQL语句实战演练

    其实这一部分你懂反射和注解就会了,通过反射和注解你可以实现一个简单的万能的增删改查。贴个新增的SQL语句代码吧!

    //insert into student_test(student_id,student_name,student_sex) values (1,"Jack","男")

    StringBuilder sql = new StringBuilder();

    Class clazz = object.getClass();

    sql.append("insert into ");

    //获取类上面的注解

    Entity entity = (Entity) clazz.getAnnotation(Entity.class);

    sql.append(entity.tableName());

    sql.append("(");

    Field[] fields = clazz.getDeclaredFields();

    for(Field field:fields){

    sql.append(field.getAnnotation(Column.class).fieldName()).append(",");

    }

    sql.deleteCharAt(sql.length()-1);

    sql.append(")");

    sql.append(" values (");

    for(Field field:fields){

    field.setAccessible(true);

    Object value = field.get(object);

    if(value.getClass().equals(String.class)){

    sql.append("\"").append(value).append("\"").append(",");

    }else {

    sql.append(value).append(",");

    }

    }

    sql.deleteCharAt(sql.length()-1);

    sql.append(")");

    System.out.println(sql.toString());

    return sql.toString();

    结语:觉得文章不错的,带上原文链接,欢迎转发,如果你发现文章中有错误可以评论或者私信我,及时修改!(wx search 全栈学习笔记)精彩美文每天为你推送!

    以上就是JAVA注解相关知识总结的详细内容,更多关于JAVA注解的资料请关注聚米学院其它相关文章!

    展开全文
  • 生命周期initMethod和destroyMethodBean定义public class Car {public Car() {System.out.println("car constructor");}public void init(){System.out.println("car init");}public void destroy(){System.out....
  • Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和任何元数据(metadata)的途径和方法。Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取...
  • Java1.5推出元注解后,时下最活跃的开源社区Spring便开始大力推崇,原本...在自定义元注解@Annotation的时候,有两个特性是必须要定义清楚的,一个是Target(注解目标),另一个就是Retention(注解生命周期,也叫声明...
  • Java1.5推出元注解后,时下最活跃的开源社区Spring便开始大力推崇,...在自定义元注解@Annotation的时候,有两个特性是必须要定义清楚的,一个是Target(注解目标),另一个就是Retention(注解生命周期,也叫声明...
  • 我们将仔细探讨其生命周期的顺序和语义,以及Java WebSocket API如何提供API和注解来支持处理这些事件。一、WebSocket协议与基于HTTP的技术不同,WebSocket具有生命周期。此生命周期周期由WebSocket协议支撑。...
  • 一、Bean的生命周期流程Bean创建 —— 初始化 —— 销毁创建:单实例:在容器启动时创建对象多实例:每次调用时创建对象初始化:都是在对象创建完成后,调用初始化方法销毁:单实例:容器关闭时,调用销毁方法多实例...
  • JAVA基础之——注解生命周期

    千次阅读 2016-05-10 21:01:59
    注解生命周期有三种,注解驻留在源文件阶段,字节码文件阶段和内存字节码阶段。 (1)注解被保留到源文件阶段  当javac把.java源文件编译成.class时,就将相应的注解去掉。这种注解生命周期就维持到...
  • Java Servlet详解(注解配置+生命周期)什么是Servlet : (Server applet)?顾名思义:服务端的小程序Servlet只是一个接口,定义了Java被浏览器访问到(Tomcat)的识别规则,我们需要定义一个类来实现Servlet接口创建一个...
  • Java WebSocket生命周期

    2016-06-08 09:02:00
    我们将仔细探讨其生命周期的顺序和语义,以及Java WebSocket API如何提供API和注解来支持处理这些事件。 一、WebSocket协议 与基于HTTP的技术不同,WebSocket具有生命周期。此生命周期周期由WebSock...
  • 咱们将仔细探讨其生命周期的顺序和语义,以及Java WebSocket API如何提供API和注解来支持处理这些事件。java1、WebSocket协议node与基于HTTP的技术不一样,WebSocket具备生命周期。今生命周期周期由WebSoc...
  • Java注解提供关于代码的信息,并且对它们注解的代码没有直接的影响。在这篇教程中,我们将学习Java注解,如何自定义注解,注解用法和如何使用反射解析...我们也可以指定注解的生命周期,或者仅在编译期间可用或者...
  • java注解 简书_java注解

    2021-03-12 10:08:57
    java注解导图:1定义:提供一种为程序元素提供元数据的方法自定义注解元注解定义:元注解的作用就是负责注解其他注解,也就是注解的注解。分类:@Target 作用域@Retention 生命周期@Documented 是否生成javadoc文档@...
  • java注解 简书_Java注解

    2021-03-04 08:58:13
    基础注解Override WebServlet元注解@Target 注解的作用目标@Retention 注解生命周期@Documented 注解是否应当被包含在javadoc中@Inherited 是否允许子类继承该注解@Target 注解的使用范围packages types (类 接口 ...
  • java注解

    2020-10-13 07:52:01
    java注解 元注解:用于描述注解的注解 @Retention 保留期 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃; 2、RetentionPolicy.CLASS:注解被保留到class文件,但...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,006
精华内容 402
关键字:

java注解生命周期

java 订阅