[编织消息框架][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处理,一切尽在掌握之中
[编织消息框架][JAVA核心技术]annotation基础的更多相关文章
- [编织消息框架][JAVA核心技术]异常基础
Java异常体系结构 Thorwable类所有异常和错误的超类,有两个子类Error和Exception,分别表示错误和异常. 其中异常类Exception又分为运行时异常(RuntimeExcept ...
- [编织消息框架][JAVA核心技术]动态代理应用12-总结
动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...
- [编织消息框架][JAVA核心技术]动态代理应用4
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用5-javassist
基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...
- [编织消息框架][JAVA核心技术]异常应用
QException是项目业务异常基类 按模块划分子类异常,方便定位那块出错 有个来源码属性code作用定位某个功能处理出错逻辑,数字类型节省内存空间,同时减少创建子类的子类 QSocketExcep ...
- [编织消息框架][JAVA核心技术]动态代理介绍
由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...
- [编织消息框架][JAVA核心技术]动态代理应用1
前面几篇介绍,终于到了应用阶段啦,我们来做一个RPC来加强学过的知识 做基础核心时先确定解决什么问题,提供什么服务,同将来扩展等 rpc 分两部份,一个是调用者,另一方是服务提供者 调用者只关心那个服 ...
- [编织消息框架][JAVA核心技术]数值与逻辑分离
为什么要分离? 业务需求是不停地变,如果把条件写进代码里,当用户需求变时要改代码发版本更新才能生效,这过程无疑是漫长的 就算是在开发期,不停的变开发者精力耗光在沟通,小修改上,无法专注逻辑部分 分离的 ...
随机推荐
- Libevent 事件循环(2)---事件被加入激活队列
由Libevent 事件循环(1) 在上文中我们提到了libevent 事件循环event_dispatch 的大致过程,以epoll为例,我们看一下事件被如何加入激活队列. //在epoll_dis ...
- 04.redis集群+SSM整合使用
redis集群+SSM整合使用 首先是创建redis-cluster文件夹: 因为redis最少需要6个节点(三主三从),为了更好的理解,我这里创建了两台虚拟机(192.168.0.109 192.1 ...
- Nginx负载均衡使用ip
upstream test1{ server 192.168.1.213; server 192.168.1.37; } server { listen 80; # default backlog=2 ...
- 深入理解javascript函数进阶系列第一篇——高阶函数
前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...
- 第三节:Creating API Endpoints (创建API路由)
对于这篇文章的标题,其实,直译就是创建api端点.但是,真的很难懂,我还是写为API路由吧.每篇,文章,我都会全部去进行实践操作,力求写一个好点的教程. 本文英文地址-->https://git ...
- ElasticSearch 学习记录之集群分片内部原理
分片内部原理 分片是如何工作的 为什么ES搜索是近实时性的 为什么CRUD 操作也是实时性 ES 是怎么保证更新被持久化时断电也不丢失数据 为什么删除文档不会立即释放空间 refresh, flush ...
- Git~GitLab当它是一个CI工具时
CI我们都知道,它是持续集成的意思,主要可以自动处理包括编译,测试,发布等一系列的过程,而GitLab也同样包含了这些功能,我们可以通过pipeline很容易的实现一个软件从编译,测试,发布的自动化过 ...
- Libcurl的编译_HTTP/HTTPSclient源代码演示样例
HTTP/HTTPSclient源代码演示样例 环境: zlib-1.2.8 openssl-1.0.1g curl-7.36 Author: Kagula LastUpdateDate: 2 ...
- 【c语言】实现一个函数,求字符串的长度,不同意创建第三方变量
// 实现一个函数,求字符串的长度.不同意创建第三方变量. #include <stdio.h> #include <assert.h> int my_strlen_no(ch ...
- iOS_4_表情排列
终于效果图: BeyondViewController.h // // BeyondViewController.h // 04_表情排列 // // Created by beyond on 14- ...