全面解析Java注解--慕课网笔记

来源:互联网 发布:怎么样开淘宝网店 编辑:程序博客网 时间:2024/06/06 19:45
第1章 概述
1-1 Java注解概述

为什么要学习注解?学习注解有什么好处?学完能做什么?

  1. 能够读懂别人的代码,特别是框架相关的代码
  2. 让编程更加简洁,代码更加清晰
  3. 让别人高看我们一眼

注解在Java1.5引入
Java提供了一种原程序中元素关联任何信息和任何元素的途径和方法

  • Java中的常见注解
  • 注解分类
  • 自定义注解
  • 注解应用实战
第2章 Java中的常见注解
2-1 JDK中的注解

JDK自带注解
- @Override
- @Deprecated
- @Suppvisewarnings

public interface Person {    public String name();    public String age();    @Deprecated    public void sing();}
public class Child implements Person{    @Override    public String name() {        return null;    }    @Override    public String age() {        return null;    }    @Override    public void sing() {    }}
public class Test {    @SuppressWarnings("deprecation")    public void sing() {        Person p = new Child();        p.sing();    }}
2-2 Java第三方注解
  • Spring
    • @Autowired
    • @Service
    • @Repository
  • Mybatis
    • @InsertProvider
    • @UpdateProvider
    • @Options
第3章 注解的分类
3-1 Java注解的分类
  • 按照运行机制分
    • 源码注解
      注解只在源码中存在,编译成.class文件就不存在了。
    • 编译时注解
      注解在源码和.class文件中都存在,如@Override、@Deprecated、@Suppvisewarnings
    • 运行时注解
      在运行阶段还起作用,甚至会影响运行逻辑的注解,如@Autowired
  • 按照来源分类
    • 来自JDK的注解
    • 来自第三方的注解
    • 我们自定义的注解

元注解:注解的注解

第4章 自定义注解
4-1 Java自定义注解
  • 自定义注解的语法要求
  • 注解的注解(元注解)
  • 使用自定义注解
  • 解析注解
@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface Description{    String desc();    String author();    int age() default 18;}
  • 使用@interface关键字定义注解
  • 成员以无参无异常方式声明
  • 可以用default为成员指定一个默认值
  • 成员类型是受限的,合法的类型包括基本类型以及String、Class、Annotation、Enumeration
  • 如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)
  • 注解类可以没有成员,没有成员的注解称为标识注解

ElementType中有:
- CONSTRUCTOR
- FIELD
- LOCAL_VARIABLE
- METHOD
- PACKAGE
- PARAMETER
- TYPE

RetentionPolicy中有:
- SOURCE
- CLASS
- RUNTIME

@Inherited:允许子类继承
@Doucument:生成javadoc时会包含注解

4-2 使用自定义注解

使用注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,…)

@Description(desc="I am eyeColor",author="Mooc boy",age=18)public String eyeColor(){    return "red";}
4-3 关于自定义注解的代码演示说明
4-4 解析注解

通过反射获取类、函数或成员上的运行时注解信息,
从而实现动态控制程序运行的逻辑。

public class ParseAnn {    public static void main(String[] args) {        try {            //1.使用类加载器加载类            Class c = Class.forName("com.ann.test.Child");            //2.找到类上面的注解            boolean isExist = c.isAnnotationPresent(Description.class);            if(isExist) {                //3.拿到注解实例                Description d = (Description)c.getAnnotation(Description.class);                System.out.println(d.value());            }            //4.找到方法上的注解            Method[] ms = c.getMethods();            for (Method m : ms) {                boolean isMExist = m.isAnnotationPresent(Description.class);                if(isMExist){                    Description d = (Description)m.getAnnotation(Description.class);                    System.out.println(d.value());                }            }            //另一种解析方法            for(Method m:ms) {                Annotation[] as = m.getAnnotations();                for (Annotation a : as) {                    if(a instanceof Description) {                        Description d = (Description)a;                        System.out.println(d.value());                    }                }            }        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}
@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface Description{    String value();//  String author();//  int age() default 18;}
@Description("I am interface")public class Person {    @Description("I am interface method")    public String name() {        return null;    };    public String age() {        return null;    };    @Deprecated    public void sing() {};}
public class Child extends Person{    @Override    public String name() {        return null;    }    @Override    public String age() {        return null;    }    @Override    public void sing() {    }}
第5章 项目实战
5-1 项目需求

项目说明:项目取自一个公司的持久层框架,用来代替Hibernate的
解决方案,核心代码就是通过注解来实现的。

需求:
1. 有一张用户表,字段包括用户ID,用户名,昵称,年龄,
性别,所在城市,邮箱,手机号。
2. 方便的对每个字段或字段的组合条件进行检索,并打印SQL。
3. 使用方式要足够简单,见代码示例。

5-2 项目实现(上)
5-3 项目实现(下)
public class Test {    public static void main(String[] args) {        Filter f1 = new Filter();        f1.setId(10);//查询id为10的用户        Filter f2 = new Filter();        f2.setUserName("lucy");//查询用户为lucy的用户        f2.setAge(18);        Filter f3 = new Filter();        f3.setEmail("liu@sina.com,zh@163.com,77777@qq.com");        String sql1 = query(f1);        String sql2 = query(f2);        String sql3 = query(f3);        System.out.println(sql1);        System.out.println(sql2);        System.out.println(sql3);        Filter2 filter2 = new Filter2();        filter2.setAmount(10);        filter2.setName("技术部");        System.out.println(query(filter2));    }    private static String query(Object f) {        StringBuilder sb = new StringBuilder();        //1.获取到class        Class c = f.getClass();        //2.获取到table的名字        boolean exists = c.isAnnotationPresent(Table.class);        if(!exists) {            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[] fArray = c.getDeclaredFields();        for (Field field : fArray) {            //4.处理每个字段对应的sql            //4.1拿到字段名            boolean fExists = field.isAnnotationPresent(Column.class);            if(!fExists) {                continue;            }            Column column = field.getAnnotation(Column.class);            String columnName = column.value();            //4.2拿到字段的值            String filedName = field.getName();            String getMethodName = "get"+ filedName.substring(0,1).toUpperCase() +                     filedName.substring(1);            Object fieldValue = null;            try {                Method getMethod = c.getMethod(getMethodName);                fieldValue =getMethod.invoke(f, null);            } catch (Exception e) {                e.printStackTrace();            }            //4.3拼装sql            if(fieldValue == null ||                    (fieldValue instanceof Integer && (Integer)fieldValue == 0)) {                continue;            }            sb.append(" and ").append(filedName);            if(fieldValue instanceof String) {                if(((String)fieldValue).contains(",")) {                    String[] values = ((String)fieldValue).split(",");                    sb.append(" in(");                    for (String v : values) {                        sb.append("'").append(v).append("'").append(",");                    }                    sb.deleteCharAt(sb.length()-1);                    sb.append(")");                }else {                    sb.append("=").append("'").append(filedName).append("'");                }            }else if(fieldValue instanceof Integer) {                sb.append("=").append(fieldValue);            }        }        return sb.toString();    }}
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Table {    String value();}
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Column {    String value();}
@Table("user")public class Filter {        @Column("id")        private int id;        @Column("user_name")        private String userName;        @Column("nick_name")        private String nickName;        @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 getNickName() {            return nickName;        }        public void setNickName(String nickName) {            this.nickName = nickName;        }        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("department")public class Filter2 {        @Column("id")        private int id;        @Column("name")        private String name;        @Column("leader")        private String leader;        @Column("amount")        private int amount;        public int getId() {            return id;        }        public void setId(int id) {            this.id = id;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public String getLeader() {            return leader;        }        public void setLeader(String leader) {            this.leader = leader;        }        public int getAmount() {            return amount;        }        public void setAmount(int amount) {            this.amount = amount;        }}
第6章 课程总结
6-1 课程总结
  1. 认识注解
  2. 注解作用范围@Target和生命周期@Retention
    • 作用范围:包、类、字段、方法的参数、局部变量
    • 生命周期:源文件SOURCE、编译CLASS、运行RUNTIME
  3. 能读懂注解

《全面解析java注解》视频地址