java 编程基础:注解(Annotation Processing Tool)注解处理器 利用注解解读类属性生成XML文件
APT的介绍:
Hibernate自动生成XML模拟:
涉及知识点:
1、自定义注释使用原注释
@Target(ElementType.FIELD) //只能修饰变量,属性
@Retention(RetentionPolicy.SOURCE) // 保留在源代码中,编译时丢弃
- 形参RoundEnvironment类型的形参roundEnvironment接收被处理的类.java源文件
- getElementsAnnotatedWith(注解类.class)方法 获取被注解修饰的元素Element 的Set集合
- 遍历集合中Element元素
- 通过集合元素Element对象getEnclosedElements方法获取Element直接包含的子元素Element
- 元素的getKind()方法获取元素类型,其中ElementKind.FIELD表示成员变量
- Element.getAnnotation(注解类.class) 方法获取对应元素的实际注解,不存在则返回null
- 字符流BufferedWriter(new FileWriter())
- 字符串StringBuilder和StringBuffer 节省内存
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @ClassName Presistent
* @projectName: object1
* @author: Zhangmingda
* @description: 该注解用来修饰数据库一个表
* date: 2021/5/19.
*/
@Target(ElementType.TYPE) //只能修饰类、接口(包括注解类型)或枚举定义
@Retention(RetentionPolicy.SOURCE) //注解只保留在源代码中,编译器直接丢弃这种注解
public @interface Presistent {
String table();
}
2、用于修饰类中属性(变量) 的两个注解
用于标识这是个表格id字段
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @ClassName Id
* @projectName: object1
* @author: Zhangmingda
* @description: 用来修饰字段是否为ID字段,以及特征属性
* date: 2021/5/19.
*/
@Target(ElementType.FIELD) //只能修饰变量(属性)
@Retention(RetentionPolicy.SOURCE) // 只保留在源代码中,编译的时候丢弃
public @interface Id {
String column();
String type();
String generator();
}
用于标识该字段的字段名和字段类型
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @ClassName Property
* @projectName: object1
* @author: Zhangmingda
* @description: 用来修饰普通字段性质
* date: 2021/5/19.
*/
@Target(ElementType.FIELD) //只能修饰变量,属性
@Retention(RetentionPolicy.SOURCE) // 保留在源代码中,编译时丢弃
public @interface Property {
String column();
String type();
}
3、编写编译注解处理工具类
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Set; /**
* @ClassName Apt
* @projectName: object1
* @author: Zhangmingda
* @description: 注解处理工具类继承AbstractProcessor
* date: 2021/5/19.
*/ @SupportedSourceVersion(SourceVersion.RELEASE_11) //支持的最新java版本
@SupportedAnnotationTypes({"Presistent","Property","Id"}) //可以处理的注解类型
public class Apt extends AbstractProcessor {
/**
* 该方法在命令行 java -processor Apt (本类类名) User.java时会自动执行
* @param set
* @param roundEnvironment
* @return
*/
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
//获取Presistent注解修饰的类
Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(Presistent.class);
//遍历被修饰的类名,注解进行处理
for (Element element: elements){
//获取javax.lang.model.element.Name类名
Name className = element.getSimpleName();
//获取注解对象
Presistent presistent = element.getAnnotation(Presistent.class);
/**
* 创建我们对应的xml文件
*/
try (BufferedWriter bw = new BufferedWriter(new FileWriter(className + "hbm.xml"))){
System.out.println();
//初始字符串初始化
StringBuilder stringBuilder = new StringBuilder("<?xml version=\"1.0\"?>\n<!DOCTYPE hibernate-mapping PUBLIC\n\t\"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n\t\"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n");
stringBuilder.append("<hibernate-mapping>\n");
//表格维度数据
stringBuilder.append("\t<class name=\"" + className + "\" table=\"" + presistent.table() + "\">\n"); //字段维度//获取所有直接包含的元素
List<? extends Element> fElements = element.getEnclosedElements();
//对所有元素判断是否被对应注解修饰,所有修饰的都处理
for (Element fElement: fElements){ //获取元素种类,如果判断为成员变量,做处理
if (fElement.getKind() == ElementKind.FIELD){ //获取成员变量上的注解
//判断否是ID注解修饰
Id id = fElement.getAnnotation(Id.class);
Property property = fElement.getAnnotation(Property.class);
if (id != null){
System.out.println(id);
System.out.println(fElement.getSimpleName());
stringBuilder.append("\t\t<id name=\"" + fElement.getSimpleName() + "\" column=\"" + id.column() + "\" type=\"" + id.type() + "\">\n");
stringBuilder.append("\t\t\t<generator class=\"" + id.generator() + "\"/>\n");
stringBuilder.append("\t\t</id>\n");
}
if (property != null){
System.out.println(property);
System.out.println(fElement.getSimpleName());
stringBuilder.append("\t\t<property name=\"" + fElement.getSimpleName() + "\" column=\"" + property.column() + "\" type=\"" + property.type() + "\"/>\n");
}
}
} //表格维度结束
stringBuilder.append("\t</class>\n");
stringBuilder.append("</hibernate-mapping>");
//写入文件
bw.write(stringBuilder.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}
4、数据库User表类
表类用Presistent注解修饰,字段用Id 和Property 注解修饰
/**
* @ClassName User
* @projectName: object1
* @author: Zhangmingda
* @description: 用于生成XML文本的对象,只获取经过修饰符修饰的对象
* date: 2021/5/19.
*/
@Presistent(table = "user")
public class User {
@Id(column = "id", type = "int", generator = "auto")
private int id; @Property(column = "name", type = "varchar")
private String name; @Property(column = "age", type = "varchar")
private String age; public User(int id, String name, String age) {
this.id = id;
this.name = name;
this.age = age;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAge() {
return age;
} public void setAge(String age) {
this.age = age;
}
}
用法:IDEA的CMD命令行执行
- 1、javac -encoding utf-8 Apt.java 编译注解处理工具类
- 2、javac -encoding utf-8 -processor Apt User.java 使用注解处理类处理表类,生成xml文件

查看生成的XML文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="User" table="user">
<id name="id" column="id" type="int">
<generator class="auto"/>
</id>
<property name="name" column="name" type="varchar"/>
<property name="age" column="age" type="varchar"/>
</class>
</hibernate-mapping>
java 编程基础:注解(Annotation Processing Tool)注解处理器 利用注解解读类属性生成XML文件的更多相关文章
- java 编程基础:注解的功能和作用,自定义注解
1,什么是注解: 从JDK5开始,Java增加了对元数据 (MetaData)的支持,也就是Annotation注解,这种注解与注释不一样,注解其实是代码里的特殊标记,这些标记可以在编译.类加载 运行 ...
- Java入门——(1)Java编程基础
Java入门--(1)Java编程基础 第二章 Java编程基础 JAVA 代码的基本格式: 修饰符 class 类名{ 程序代码 } 2.1关键字:赋予了特殊含义的单词. 2.2标识符: ...
- Bean 注解(Annotation)配置(1)- 通过注解加载Bean
Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...
- Java开发知识之Java编程基础
Java开发知识之Java编程基础 一丶Java的基础语法 每个语言都有自己的语法规范.例如C++ 入口点是main. 我们按照特定格式编写即可. Java也不例外. Java程序的语法规范就是 Ja ...
- java编程基础二进制
0.java编程基础 01.二进制(原码,反码,补码) 02.位运算 03.移位运算符 二进制 原码,反码,补码 1.基本概念 二进制是逢2进位的进位制,0,1是基本算符. 现在的电子计算机技术全部使 ...
- Java编程基础-面向对象(中)
本章承接Java编程基础-面向对象(上)一文. 一.static关键字 在java中,定义了一个static关键字,它用于修饰类的成员,如成员变量.成员方法以及代码块等,被static修饰的成员具备一 ...
- Java编程基础——数组和二维数组
Java编程基础——数组和二维数组 摘要:本文主要对数组和二维数组进行简要介绍. 数组 定义 数组可以理解成保存一组数的容器,而变量可以理解为保存一个数的容器. 数组是一种引用类型,用于保存一组相同类 ...
- Java编程基础——流程控制
Java编程基础——流程控制 摘要:本文主要介绍Java编程中的流程控制语句. 分类 流程控制指的是在程序运行的过程中控制程序运行走向的方式.主要分为以下三种: 顺序结构:从上到下依次执行每条语句操作 ...
- Java编程基础——运算符和进制
Java编程基础——运算符和进制 摘要:本文主要介绍运算符和进制的基本知识. 说明 分类 Java语言支持如下运算符: ◆ 算术运算符:++,--,+,-,*,/,%. ◆ 赋值运算符:=,+=,-= ...
随机推荐
- 【HTML】基础
HTML基础 2019-07-23 10:16:28 by冲冲 在线编辑HTML/CSS/JS效果,实时查看效果 https://c.runoob.com/front-end/61 1. 概念 ① ...
- docker 启动报错:Docker.Core.Backend.BackendException: Error response from daemon: open \\.\pipe\docker_e
win10 docker启动后报错: Docker.Core.Backend.BackendException:Error response from daemon: open \\.\pipe\do ...
- 树形DP详解+题目
关于树形dp 我觉得他和线性dp差不多 总结 最近写了好多树形dp+树形结构的题目,这些题目变化多样能与多种算法结合,但还是有好多规律可以找的. 先说总的规律吧! 一般来说树形dp在设状态转移方程时都 ...
- Python os模块与sys模块
1.os模块简单使用及说明 # -*- coding:utf-8 -*- """ os模块主要用于系统,处理程序与系统交互问题 大部分如属性等功能在linux系统中会使用 ...
- SpringBoot整合Shiro 一:搭建环境
Java项目的安全框架一般使用 shiro 与 spring security 具体怎么选择可以参考文章:安全框架 Shiro 和 Spring Security 如何选择 我这里选择使用Shiro ...
- 求解线性递推方程第n项的一般方法
概述 系数为常数,递推项系数均为一次的,形如下面形式的递推式,称为线性递推方程. \[f[n]=\begin{cases} C &n\in Value\\ a_1 f[n-1]+a_2 f[n ...
- A Child's History of England.16
CHAPTER 5 ENGLAND UNDER CANUTE THE DANE Canute reigned eighteen years. He was a merciless King at fi ...
- android TabLayout设置选项卡之间的距离无效已解决
根据下面的链接设置完距离后无法生效 https://www.jb51.net/article/131304.htm layout <com.google.android.material.tab ...
- CountDownLatch原理
正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.在Java并发中,countdownlatch的概念是一 ...
- 基于阿里云ecs(centos 7) 安装jenkins
1. 安装好 jdk 2. 官网(https://pkg.jenkins.io/redhat-stable/)下载rpm包(稳定版): wget https://pkg.jenkins.io/redh ...