zoukankan      html  css  js  c++  java
  • [编织消息框架][JAVA核心技术]annotation基础

    应用动态代理技术要先掌握annotation技术

    注解是JDK1.5之后才有的新特性,JDK1.5之后内部提供的三个注解

    @Deprecated 意思是“废弃的,过时的

    @Override 意思是“重写、覆盖

    @SuppressWarnings 意思是“压缩警告

    注解可以加在类名,方法,参数,属性等,为开发者自定义编译处理,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解

    所以注解是做框架必备技术

    先来看看如何书写Annotation

    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.CLASS)
    public @interface TestAnno{
        int value();
        String name() default "";
    }

    1.书写跟interface一样,前面加了个@符号

    2.属性可以加默认值

    3.@Target 是使用权,作用于类名,方法,参数,属性等地方,可以有多个使用权

    4.@Retention 是决定注解生命周期 ,分别为 SOURCE,CLASS,RUNTIME 第一个权限越低

      SOURCE 只是在源码上保留,java文件编译成class去掉

      CLASS 保留在class但在加载时忽略

      RUNTIME 保留在class并加载时保留

    来验证下@Retention

    import java.lang.reflect.Field;
    
    public class TestAnnotation {
        @TestAnno(value = 1, name = "a")
        private int a;
    
        public static void main(String[] args) {
        for (Field field : TestAnnotation.class.getDeclaredFields()) {
            TestAnno anno =   field.getAnnotation(TestAnno.class);
            System.out.println(anno.value());
        }
        }
    }

    执行结果:

    Exception in thread "main" java.lang.NullPointerException
    at com.eyu.onequeue.TestAnno.main(TestAnno.java:13)

    我们来修改下@Retention(RetentionPolicy.RUNTIME)

    再执行就正常了

    接下来看看spring是如何应用注解技术的

    如spring切面拦截

    @Aspect
    public class TestAspect {
    @Around(
    "@annotation(annotation class)") public Object exceptionHandler(ProceedingJoinPoint pjp) throws Throwable { Object result = pjp.proceed(pjp.getArgs()); return result; } }

    1.@Aspect将处理范围准确到类,一个处理对应一个注解

    2.扫描每个类的属性或方法,提取@Around的信息

    3.提取后应缓存起来,不用每次重新处理

    我们来看下为什么要缓存起来

    在main里加一行System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

    运行后 用jd-gui打开 $Proxy1,只是分析value方法,可以看到用反射invoke执行结果,而invoke执行比较耗时

      public final int value()
      {
        try
        {
          return ((Integer)this.h.invoke(this, m4, null)).intValue();
        }
        catch (Error|RuntimeException localError)
        {
          throw localError;
        }
        catch (Throwable localThrowable)
        {
          throw new UndeclaredThrowableException(localThrowable);
        }
      }

     接下来看看Hibernate应用

    @Entity
    @NamedQueries({ 
        @NamedQuery(name = Player.ACCOUNT2ID, query = "select account, id from Player"),
        @NamedQuery(name = Player.ONLINE_IDS, query = "select id from Player WHERE logined = 1"),
    })
    public class Player {
    
        static final String ACCOUNT2ID = "Player_Account2Id";
    
        public static final String ONLINE_IDS = "Player_ONLINE_IDS";
        
        static final String IDX_ACCOUNT = "Player_Account";
    
        @Id
        private long id;
     
        @Index(name = IDX_ACCOUNT)
        @Column(unique = true, nullable = false)
        private String account;
    
        private Date createdOn;
      //.....省略 }

    1.@Entity是处理的标记 @Id作为table主健

    2.@Column 映射列属性,如自定义列名,是否唯一,不能为NULL等

    3.@Index 生成索引

    4.@NamedQuery 绑定hql语句

    小结:只要在原对象结构基础上加上注解,无破坏性,优雅的方式就能实现复杂的功能,还有个好处就是硬编译写在class上的,不用每次调用再去执行其它IO处理,一切尽在掌握之中

  • 相关阅读:
    Roslyn 编译器和RyuJIT 编译器
    go语言---defer
    go语言---for
    go语言--time.After
    go语言---for range
    用gulp打包带参数资源做法与asp.net/java项目结合的自动构建方案探讨
    JQuery判断元素是否存在
    gulp实现打包js/css/img/html文件,并对js/css/img文件加上版本号
    gulp同步执行任务
    gulp-rev同时将js和css文件写在一个rev-manifest.json文件里面的方式探讨
  • 原文地址:https://www.cnblogs.com/solq111/p/6639910.html
Copyright © 2011-2022 走看看