注解

作者: sundern | 来源:发表于2021-04-04 18:13 被阅读0次

    Java注解

    • @Deprecated:标记方法或类过时
    • @SuppressWarning: 在确定结果的前提下忽略警告

    第三方注解

    • @Autoware

    按运行机制分

    • 源码注解(SOURCE):只在源码中存在
    • 编译时注解(CLASS):源码和.class文件时都存在。@Override
    • 运行时注解(RUNTIME): 源码和.class文件存在、程序运行时也存在。@Autoware

    按来源分

    • JDK
    • 第三方
    • 自定义
      元注解 :给注解用的注解

    自定义注解

    1. 语法:
    • 使用@interface关键字
    • 成员变量要生命成无参函数形式,并且无异常,只能是基本数据类型和String,使用default关键字赋默认值
    • 只有一个成员变量时,必须命名为value()
    @Target({ElementType.METHOD,ElementType.TYPE})
    @Rentention(RententionPolicy.RUNTIME)
    @Inherited
    @Document
    public @interface Discription{
      String desc();
      String author();
      int age() default 18;
    }
    
    1. 元注解
    • @Target:注解适用范围,可以设置多个。
      取值:
    ElementType.CONSTRUCTOR
    ElementType.FIELD
    ElementType.LOCAL_VARIABLE //局部变量
    ElementType.METHOD
    ElementType.PACKAGE
    ElementType.PARAMETER
    ElementType.TYPE //类,接口
    
    • @Rentention:注解生命周期
      取值:
    RententionPolicy.SOURCE // 源码
    RententionPolicy.CLASS // 编译
    RententionPolicy.RUNTIME //运行
    
    • @Inherited:允许注解继承
    • @Document:生成doc时生成注解信息
    1. 使用注解
    @Discription(desc="我是一段描述",author="yujian",age=18)
    public String getMyName(){
      return "yujian";
    }
    
    1. 解析注解
      通过反射获取类运行时注解信息,从而动态控制类的运行逻辑。

    实战

    自定义table和column注解映射字段和表,查询数据,打印书SQL
    table和column注解:

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

    User类使用table和column注解

    @Table("user")
    public class User {
    
        @Column("id")
        private String id;
    
        @Column("name")
        private String name;
    
        @Column("email")
        private String email;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    

    根据注解获取标名和字段名,根据反射获取字段值:

            //获取class
            Class c = user.getClass();
            //获取table名称
            if (!c.isAnnotationPresent(Table.class)){
                return null;
            }
            Table table = (Table) c.getAnnotation(Table.class);
            System.out.println(table.value());
            //获取field名称
            Field[] fields = c.getDeclaredFields();
            for (Field field : fields){
                if (field.isAnnotationPresent(Column.class)){
                    Column column = field.getAnnotation(Column.class);
                    System.out.print(column.value() + ":");
                    //通过反射获取对象值
                    String fieldName = field.getName();
                    String methodName = "get"
                            + fieldName.substring(0,1).toUpperCase()
                            + fieldName.substring(1);
                    try {
                        Method method = c.getMethod(methodName);
                        System.out.println(method.invoke(user));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
    

    常见概念

    • 为什么需要把 @Autowired写在构造器上:注入注解要等类构造完成才会注入外部依赖,但变量是按顺序加载的,容易出现空指针异常,使用构造器注入在调用时去初始化,能保证已经注入了外部依赖。

    • @Autowired只按照byType 注入;
      @Resource默认按byName自动注入,也提供按照byType 注入;

    • @Configuration:配置文件,与@Bean连用可配置单个Bean,eg.@Bean(name="user")

    • @EnableAutoConfiguration:配合spring.factories文件将配置文件装配到spring中,参考

    • @ComponentScan:叠加在配置文件类上,可以定策略扫描Bean,默认扫描配置文件同包的类,注意类上需要配置

    //@Component注解。basePackages定义扫描的包
    @ComponentScan(basePackages = { ” com.springboot . chapter3 . pojo” })
    //basePackageClasses 定义扫描的类
    @ComponentScan(basePackageClasses = {User. class} ) 
    //还有 includeFilters 和 excludeFilters 
    @ComponentScan(basePackages = "com.springboot.chapter3 . * ”, excludeFilters = {@Filter(classes = {Service . class})}) 。
    

    相关文章

      网友评论

          本文标题:注解

          本文链接:https://www.haomeiwen.com/subject/heptkltx.html