[编织消息框架][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处理,一切尽在掌握之中

posted @ 2017-03-29 15:30  solq321  阅读(247)  评论(0编辑  收藏  举报