【iMooc】全面解析java注解

在慕课上学习了一个关于java注解的课程,下面是笔记以及一些源码。

Annotation——注解

1.JDK中的注解

JDK中包括下面三种注解:

@Override:标记注解(marker annotation),重写,父类写的方法,如果子类继承了父类,就要重写父类的方法。

@Deprecated:表示过时的语法加上这个注解之后,该方法上会出现一道删除线

@SuppressWarning:忽略警告,压制警告。如果某语句前面出现警告,加上这个注解,警告就会消失。

举例如下:

父类 一个Person接口: @Deprecated表示该方法过时。

package com.ann.test;

public interface Person {
    public String name();

    public int age();

    @Deprecated
    public void sing();
}

子类Child 集成父类,必须 重写@Override父类的所有方法。

package com.ann.test;

public class Child implements Person{

    @Override
    public String name() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int age() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void sing() {
        // TODO Auto-generated method stub

    }

}

测试代码: 测试代码中调用了过时的sing()函数,产生警告。使用@SuppressWarnings注解 ,可消除警告。

package com.ann.test;

public class Test {
    @SuppressWarnings("deprecation")
    public void sing() {
        Person p = new Child();
        p.sing();
    }
}

2.常见第三方注解:

Spring:

  • @Autowired:不用配置文件,可以自动生成Dao文件注入进去
  • @Serice
  • @Repository

Mybatis:

  • @InsertProvider
  • UpdataProvider
  • @Options

3.注解分类:

按照运行机制:

  • 编码注解:只存在源码中
  • 编译时注解:存在于源码与.class中 如@override、@Deprecated、@SuppressWarning
  • 运行时注解:运行时将成员变量自动注入(可能会影响运行逻辑)如Spring中的@AutoWired

按照来源:

  • JDK注解
  • 第三方注解(Spring等)
  • 自定义注解

4.自定义注解

可新建一个Annotation,@interface表示注解。在自定义注解中,

  1. 成员变量必须是无参无异常的形式,可以设置使用default设置默认值
  2. 成员变量的类型:基本数据类型、String、class、Annotation、Enumeration
  3. 成员变量只有一个的时候,一般取名为value();使用的时候,可以直接赋值
  4. 可以没有成员
package com.ann.test;

import java.lang.annotation.Documented;
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;

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Decription {

    String desc();

    String author();

    int age() default 18;
}
@Target:表示注解作用域,关键字包括Constructor(构造函数)、Field(变量)、Local_veriable、method、package、parameter、tyoe(类,接口)
@Retention:生命周期:source、class、runtime
@Inherited:可以被子类继承
@Documented:生成javadoc时包含注解信息

自定义注解的使用:@<注解名>(<成员名1>=<value1>,.......)如下:
package com.ann.test;
@Decription(desc="I am class description", author = "YM")
public class Child implements Person{

    @Override
    @Decription(desc="I am method description", author = "YM", age = 18)
    public String name() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public int age() {
        // TODO Auto-generated method stub
        return 0;
    }
    @Override
    public void sing() {
        // TODO Auto-generated method stub

    }
}

5.解析注解

  1. 首先使用加载器加载类
  2. 找到类上的注解
  3. 拿到注解实例
  4. 找到方法上的注解

另一种解析方法:以方法上的注解为例

  1. 遍历所有的方法
  2. 拿出所有的注解
  3. 遍历所有注解


package com.ann.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class ParseAnn {
public static void main(String[] args) {
    try {
        //1.使用类加载器加载类
        Class c=Class.forName("com.ann.test.Child");
        //2找到类上的注解
        boolean isExis = c.isAnnotationPresent(Decription.class);
        if(isExis){
            //3.拿到注解实例
            Decription d=(Decription) c.getAnnotation(Decription.class);
            System.out.println(d.desc());
        }
        //4.找到方法上的注解
        Method[] ms=c.getMethods();
        for(Method m:ms){
            boolean isMExis=m.isAnnotationPresent(Decription.class);
            if(isMExis){
                Decription mds=(Decription)m.getAnnotation(Decription.class);
                System.out.println(mds.desc());
            }
        }

        //另外一种解析方法
        //1.遍历所有方法
        for(Method m:ms){
            //2拿出所有注解
            Annotation[] an=m.getAnnotations();
            //3遍历所有注解
            for(Annotation a:an){
                //如果a是我们自定义注解的实例
                if(a instanceof Decription)
                {    //将a强转成Decription类
                    Decription d= (Decription)a;
                    System.out.println(d.desc());
                }
            }
        }
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

输出:

I am class description
I am method description
I am method description

6.注解实战:

需求:一张用户表。自动的对每个字段或字段的组合条件进行检索,拼接sql语句,并打印

Filter.class

package com.ann.dao;

@Table("user")
public class Filter {
    @Column("id")
    private int id;
    @Column("userName")
    private String userName;
    @Column("nikeName")
    private String nikeName;
    @Column("age")
    private int age;
    @Column("city")
    private String city;
    @Column("email")
    private String email;
    @Column("mobile")
    private String mobile;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getNikeName() {
        return nikeName;
    }

    public void setNikeName(String nikeName) {
        this.nikeName = nikeName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}

Table (自定义注解)作用域为TYPE表示类

package com.ann.dao;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    public String value();
}

Column (自定义注解)

package com.ann.dao;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    public String value();
}

Test :

package com.ann.dao;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    // 1.首先考虑代码怎么与数据库做映射 filter是与数据库关系最紧密的类-转到filter
    // 2需要考虑query方法如何实现
    public static void main(String[] args) {
        Filter f1 = new Filter();
        f1.setId(10);// 查询id为10的用户
        Filter f2 = new Filter();
        f2.setUserName("Tom");// 查询用户名为tom的用户
        f2.setAge(18);
        Filter f3 = new Filter();
        f3.setEmail("[email protected],[email protected]");
        String sql1 = query(f1);
        String sql2 = query(f2);
        String sql3 = query(f3);
        System.out.println("sql1:" + sql1);
        System.out.println("sql2:" + sql2);
        System.out.println("sql3:" + sql3);
        //写一个filter可以应用到不同的表中
        Filter2 filter2= new Filter2();
        filter2.setAmount(10);
        filter2.setId(1);
        filter2.setName("技术");
        System.out.println(query(filter2));
    }

    private static String query(Object f) {
        // 首先用一个StringBuilder来存储字符串表示sql语句
        StringBuilder sb = new StringBuilder();
        // 1获取class
        Class c = f.getClass();
        // 2.获取table名
        boolean isCExis = c.isAnnotationPresent(Table.class);
        if (!isCExis) {
            return null;
        }
        Table t = (Table) c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append("select * from ").append(tableName).append(" where 1=1");
        // 3.遍历所有字段
        Field[] field = c.getDeclaredFields();
        for (Field fi : field) {
            // 4.处理每个字段对应的sql
            // 4.1拿到字段的名字
            boolean isFExis = fi.isAnnotationPresent(Column.class);
            if (!isFExis) {
                continue;
            }
            Column col = fi.getAnnotation(Column.class);
            String columnName = col.value();
            // 4.2拿到字段的值(反射)
            String fieldName = fi.getName();// 字段名
            // 先拿到get方法的名字
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                fieldValue = getMethod.invoke(f);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 4.3拼接
            if (fieldValue == null || (fieldValue instanceof Integer && (Integer) fieldValue == 0)) {
                continue;
            }
            sb.append(" and ").append(fieldName);
            if (fieldValue instanceof Integer) {
                sb.append(" = ").append(fieldValue);
            } else if (fieldValue instanceof String) {
                if (((String) fieldValue).contains(",")) {// 邮箱格式包含,表示有多种选择
                    String[] string = ((String) fieldValue).split(",");
                    sb.append(" in (");
                    for(String str:string){
                        sb.append("‘").append(str).append("‘").append(",");
                    }
                    sb.deleteCharAt(sb.length()-1);
                    sb.append(")");
                } else {
                    sb.append(" = ‘").append(fieldValue).append("‘");
                }

            }
        }
        return sb.toString();
    }
}
sql1:select * from user where 1=1 and id = 10
sql2:select * from user where 1=1 and userName = ‘Tom‘ and age = 18
sql3:select * from user where 1=1 and email in (‘[email protected]‘,‘[email protected]‘)


原文地址:https://www.cnblogs.com/yumiaomiao/p/8525162.html

时间: 2024-10-18 12:43:14

【iMooc】全面解析java注解的相关文章

全面解析Java注解

1.  了解注解 我们有必要对JDK 5.0新增的注解(Annotation)技术进行简单的学习,因为Spring 支持@AspectJ,而@AspectJ本身就是基于JDK 5.0的注解技术.所以学习JDK 5.0的注解知识有助于我们更好地理解和掌握Spring的AOP技术. 对于Java开发人员来说,在编写代码时,除了源程序以外,我们还会使用 Javadoc标签对类.方法或成员变量进行注释,以便使用Javadoc工具生成和源代码配套的Javadoc文档.这些@param.@return 等J

Java注解入门

注解的分类 按运行机制分: 源码注解:只在源码中存在,编译后不存在 编译时注解:源码和编译后的class文件都存在(如@Override,@Deprecated,@SuppressWarnings) 运行时注解:能在程序运行时起作用(如spring的依赖注入) 按来源分: 来自JDK的注解 第三方的注解 自定义的注解 自定义注解   如下实例给出了自定义注解的基本方法 1 package com.flypie.annotations; 2 3 import java.lang.annotatio

Java注解全面解析(转)

1.基本语法 注解定义看起来很像接口的定义.事实上,与其他任何接口一样,注解也将会编译成class文件. @Target(ElementType.Method) @Retention(RetentionPolicy.RUNTIME) public @interface Test {} 除了@符号以外,@Test的定义很像一个空的接口.定义注解时,需要一些元注解(meta-annotation),如@Target和@Retention @Target用来定义注解将应用于什么地方(如一个方法或者一个

[笔记]Java注解全面解析

JAVA注解 注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来对这些元素进行说明,注释. 1.注解分类 1.1按照运行机制分类 源码注解 注解只在源码中存在,编译成.class文件就不存在了 编译时注解 注解在源码和.class文件中都存在 比如: @Override @Deprecated @Suppvisewarnings 运行时注解 在运行

Java注解教程:自定义注解示例,利用反射进行解析

Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入的,目前已被广泛应用于各种Java框架,如Hibernate,Jersey,Spring.注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效. 在注解诞生之前,程序的元数据存在的形式仅限于java注释或javadoc,但注解可以提供更多

java注解(Annotation)解析

注解(Annotation)在java中应用非常广泛.它既能帮助我们在编码中减少错误,(比如最常见的Override注解),还可以帮助我们减少各种xml文件的配置,比如定义AOP切面用@AspectJ模式代替Schema模式,特别是最近接触了一点Spring MVC,每次编写Controller的时候用@RequestMapping(),@RequestParam,@ResponseBody等等. 我们所用的java中自带的注解都是定义好了的,直接拿来用,它就能发挥作用.当然了,自己也可以定义注

Java注解(3)-注解处理器(编译期|RetentionPolicy.SOURCE)

注解的处理除了可以在运行时通过反射机制处理外,还可以在编译期进行处理.在编译期处理注解时,会处理到不再产生新的源文件为止,之后再对所有源文件进行编译. Java5中提供了apt工具来进行编译期的注解处理.apt是命令行工具,与之配套的是一套描述"程序在编译时刻的静态结构"的API:Mirror API(com.sun.mirror.*).通过Mirror API可以获取到被注解的Java类型元素的信息,从而提供自定义的处理逻辑.具体的处理工具交给apt来处理.编写注解处理器的核心是两个

Java注解项目实战即模拟Hibenernate生成sql语句

整理了近期学习java注解的部分代码 ,借助java注解模拟Hibenernate ORM模型建立对象与sql语句的映射 Table 注解的创建 package com.imooc.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.

java注解例子

java注解在web框架中使用比较广泛,这使得对象之间的关系配置起来更加容易 目前web框架中最常用的两种配置对象依赖关系的方式就是注解和xml配置文件的方法,api配置相对来说用的少一些, 下面实现一个Table注解来实现数据库表和实体bean之间的对应关系,实现一个Column注解来实现数据库表中每个字段和实体bean每个属性之间的 对应关系.java中的orm基本上就是根据这种思想来实现的. Table注解代码: package com.panther.dong.annotation.an