如何做网站么做网站商标分类
如何做网站么,做网站商标分类,网页制作价格表,制作网站设计的公司用自定义注解做点什么
前言 你不一定听过注解#xff0c;但你一定对Override不陌生。
当我们重写父类方法的时候我们就看到了Override。我们知道它表示父类方法被子类重写了。
现在告诉你#xff0c;Override就是一个注解。
也许你会疑惑注解是什么#xff1f; 注解但你一定对Override不陌生。
当我们重写父类方法的时候我们就看到了Override。我们知道它表示父类方法被子类重写了。
现在告诉你Override就是一个注解。
也许你会疑惑注解是什么 注解annotation是JDK5之后引进的新特性是一种特殊的注释之所以说它特殊是因为不同于普通注释comment能存在于源码而且还能存在编译期跟运行期会最终编译成一个.class文件所以注解能有比普通注释更多的功能。
接下来先入个门然后通过实战来证明注解有多“猛”。
PS : 如果已经了解的小伙伴可自行跳到 自定义注解实战。
自定义注解入门 我们对于注解的认识大多数来源于标准注解也称为内建注解。
标准注解表示的意义Override用于标识该方法继承自超类 当父类的方法被删除或修改了编译器会提示错误信息Deprecated表示该类或者该方法已经不推荐使用 如果用户还是要使用会生成编译的警告SuppressWarnings用于忽略的编译器警告信息
Java不仅仅提供我们原有的注解使用它还允许我们自定义注解。比如你可以像这样
public interface DoSomething {public String name() default write;
}这是最简单的注解声明。 尽管看上去像是接口的写法但完全不是一回事。这一点要注意。 而使用注解也很简单可以像这样
DoSomething(name walidake)//可以显式传值进来此时namewalidake
public class UseAnnotation {}DoSomething//如果不传值则默认name我们定义的默认值即我们上面定义的write
public class UseAnnotation {}需要注意的是当注解有value()方法时不需要指明具体名称。
public interface DoSomething {public String value();public String name() default write;
}DoSomething(walidake)
public class UseAnnotation {}然而“最简单的自定义注解”并没有特别的意义。所以这时候我们需要引入一个元注解的概念。
我们需要知道这些概念 “普通注解”只能用来注解“代码”而**“元注解”只能用来注解 “普通注解”**。 自定义注解是“普通注解”。
JDK5时支持的元注解有Documented Retention Target Inherited接下来分别介绍它们修饰注解的效果。
Documented
interface DocumentedAnnotation{}interface UnDocumentedAnnotation{}DocumentedAnnotation
UnDocumentedAnnotation
public class UseDocumentedAnnotation{}打开小黑窗运行javadoc UseDocumentedAnnotation.java
运行结果 结论可以看到被Documented修饰的注解会生成到javadoc中如DocumentedAnnotation。 而不被Documented修饰的注解UnDocumentedAnnotation不会生成到javadoc中。
注解的级别 Retention可以设置注解的级别分为三种都有其特定的功能。 这个元注解是我们关注的重点后面实战我们会用到。
注解级别存在范围主要用途SOURCE 源码级别注解只存在源码中功能是与编译器交互用于代码检测。 如Override,SuppressWarings。 额外效率损耗发生在编译时CLASS 字节码级别注解存在源码与字节码文件中主要用于编译时生成额外的文件如XMLJava文件等但运行时无法获得。 这个级别需要添加JVM加载时候的代理javaagent使用代理来动态修改字节码文件RUNTIME 运行时级别注解存在源码字节码与Java虚拟机中主要用于运行时反射获取相关信息
限制注解使用的范围 注解默认可以修饰各种元素而使用Target可以限制注解的使用范围。
例如可以限定注解只能修饰方法。
Target(ElementType.METHOD)
Retention(RetentionPolicy.SOURCE)
public interface Override {}上面的代码将注解的使用范围限制在了方法上而不能用来修饰类。
试着用Override修饰类会得到“The annotation Override is disallowed for this location”的错误。
Target支持的范围参见ElementType
1 类接口注解;
2 属性域
3 方法
4 参数
5 构造函数
6 局部变量
7 注解类型
8 包注解的继承 Inherited可以让注解类似被“继承”一样。 通过使用Inherited可以让子类对象使用getAnnotations()获取父类Inherited修饰的注解。
Inherited
Retention(RetentionPolicy.RUNTIME)
interface Inheritable{}interface UnInheritable{}public class UseInheritedAnnotation{UnInheritableInheritablepublic static class Super{}public static class Sub extends Super {}public static void main(String... args){Super instancenew Sub();//result : [com.walidake.annotation.util.Inheritable()]System.out.println(Arrays.toString(instance.getClass().getAnnotations()));}
}我们干脆用Documented查看类结构。发现 这是不是恰恰证明了这种是伪继承的说法而不是真正的继承。
自定义注解实战 引言 Java Web开发中对框架的理解和掌握是必须的。而在使用大多数框架的过程中一般有两种方式的配置一种是基于xml的配置方式一种是基于注解的方式。然而越来越多的程序员我在开发过程中享受到注解带来的简便并义无反顾地投身其中。
ORM框架像HibernateMybatis就提供了基于注解的配置方式。我们接下来就使用自定义注解实现袖珍版的Mybatis袖珍版的Hibernate。
这很重要 说明实战的代码会被文章末尾附上。而实际上在之前做袖珍版框架的时候并没有想到会拿来做自定义注解的Demo。因此给出的代码涉及了其他的一些技术例如数据库连接池动态代理等等比较杂。 在这个篇幅我们只讨论关于自定义注解的问题至于其他的技术后面会开多几篇博文阐述。当然这么多前辈面前不敢造次有个讨论学习的氛围是很好的~
那么在自定义注解框架前我们需要花点时间浏览以下几个和Annotation相关的方法。
方法名用法Annotation getAnnotation(Class annotationType)获取注解在其上的annotationTypeAnnotation[] getAnnotations()获取所有注解isAnnotationPresent(Class annotationType)判断当前元素是否被annotationType注解Annotation[] getDeclareAnnotations()与getAnnotations() 类似但是不包括父类中被Inherited修饰的注解
Mybatis 自定义注解
本节目标自定义注解实现Mybatis插入数据操作。 本节要求细心观察使用自定义注解的步骤。
Step 1 : 声明自定义注解。
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.METHOD)
public interface Insert {public String value();
}Step 2 : 在规定的注解使用范围内使用我们的注解
public interface UserMapper {Insert(insert into user (name,password) values (?,?))public void addUser(String name,String password);}
Step 3 : 通过method.getAnnotation(Insert.class).value()使用反射解析自定义注解得到其中的sql语句
//检查是否被Insert注解修饰
if (method.isAnnotationPresent(Insert.class)) {//检查sql语句是否合法//method.getAnnotation(Insert.class).value()取得Insert注解value中的Sql语句sql checkSql(method.getAnnotation(Insert.class).value(),Insert.class.getSimpleName());//具体的插入数据库操作insert(sql, parameters);
}Step 4 : 根据实际场景调用Step 3的方法
UserMapper mapper MethodProxyFactory.getBean(UserMapper.class);
mapper.addUser(walidake,665908);
运行结果 以上节选自annotation中Mybatis部分。具体CRUD操作请看源码。
总结一下从上面学到的东西 1.声明自定义注解并限制适用范围因为默认是通用 2.规定范围内使用注解 3.isAnnotationPresent(Insert.class)检查注解getAnnotation(Insert.class).value()取得注解内容 4.根据实际场景应用
Hibernate 自定义注解
本节目标自定义注解使实体自动建表即生成建表SQL语句 本节要求动手操作把未给全的代码补齐。 本节规划仿照Hibernate我们大概会需要TableColumn还有id我们这里暂且声明为PrimaryKey
仿照自定义Mybatis注解的步骤
/*** 可根据需要自行定制功能*/
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.TYPE)
public interface Table {String name() default ;}Retention(RetentionPolicy.RUNTIME)
Target(ElementType.FIELD)
public interface Column {// 列名 默认为String name() default ;// 长度 默认为255int length() default 255;// 是否为varchar 默认为trueboolean varchar() default true;// 是否为空 默认可为空boolean isNull() default true;
}/*** 有需要可以拆分成更小粒度* author walidake**/
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.FIELD)
public interface PrimaryKey {String name() default ;
}
完成Step 1接下来是Step 2。
Table
public class Person {PrimaryKeyprivate int id;Column(isNull false, length 20)private String username;...
}Step 3新建一个叫做SqlUtil的类使用Class实体类.isAnnotationPresent(Table.class)取到Table注解的内容。
而我们如何取到Column和PrimaryKey的内容 使用反射我们可以很容易做到。
// 反射取得所有Field
Field[] fields clazz.getDeclaredFields();
...
...
// 获取注解对象
column fields[i].getAnnotation(Column.class);
// 设置访问私有变量
fields[i].setAccessible(true);
// 取得Column的内容
columnName .equals(column.name()) ? fields[i].getName(): column.name();
反射的内容后面再写。感觉每一篇都给自己挖了很多坑后面去填
Step 4套入使用场景
String createSql SqlUtil.createTable(clazz);
...
connection.createStatement().execute(createSql);运行结果 运行结果正确
自此我们完成了实战模块的内容。当然关于Hibernate的CRUD也可以用同样的方法做到更进一步还可以把二级缓存整合进来实现自己的一个微型框架。尽管现有的框架已经很成熟了但自己实现一遍还是能收获很多东西。
可以看出来注解简化了我们的配置。每次使用注解只需要注解名就可以了就跟吃春药一样“爽”。不过由于使用了反射后劲太“猛”,jvm无法对代码优化影响了性能。这一点最后也会提及。
另外提一点之前想格式化hibernate生成的SQL做大量搜索后被告知“Hibernate 使用的是开源的语法解析工具 Antlr需要进行 SQL 语法解析将 SQL 语句整理成语法树”。也算一个坑吧~ 不过后来找到一个除了建表SQL以外的格式化工具类觉得还不错就也分享了。可以在源码中找到。
最后说点什么 可以发现我们使用运行时注解来搭建我们的袖珍版ORM框架因为运行时注解来搭建框架相对容易而且适用性也比较广搭建的框架使用起来也比较简单。但在此基础上因为需要用到反射其效率性能相对不高。因此多数Web应用使用运行时注解而像Android等对效率性能要求较高的平台一般使用源码级别注解来搭建。下一节我们讨论怎么玩一玩源码级注解。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88724.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!