- 浏览: 55846 次
- 性别:
- 来自: 杭州
最新评论
package annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ExtractInterface { String value(); }
package annotations; //包含待解析annotation的类 @ExtractInterface("IMultiplier") public class Multiplier { public int multiply(int x, int y) { int total = 0; for (int i = 0; i < x; i++) total = add(total, y); return total; } private int add(int x, int y) { return x + y; } }
package annotations; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.Modifier; import com.sun.mirror.declaration.ParameterDeclaration; import com.sun.mirror.declaration.TypeDeclaration; //annotation处理类 public class InterfaceExtractorProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env; private List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>(); public InterfaceExtractorProcessor(AnnotationProcessorEnvironment env) { this.env = env; } @Override public void process() { for (TypeDeclaration type : env.getSpecifiedTypeDeclarations()) { ExtractInterface intf = type.getAnnotation(ExtractInterface.class); if (intf == null) continue; for (MethodDeclaration method : type.getMethods()) if (method.getModifiers().contains(Modifier.PUBLIC) && !method.getModifiers().contains(Modifier.STATIC)) methods.add(method); if (methods.size() > 0) { PrintWriter writer = null; try { writer = env.getFiler().createSourceFile(intf.value()); writer.println("package " + type.getPackage().getQualifiedName() + ";"); writer.println(); writer.println("public interface " + intf.value() + " {"); for (MethodDeclaration method : methods) { writer.print("\tpublic " + method.getReturnType() + " " + method.getSimpleName() + "("); Collection<ParameterDeclaration> params = method .getParameters(); int i = 0; int len = params.size(); for (ParameterDeclaration param : params) { writer.print(param.getType() + " " + param.getSimpleName()); if (++i < len) writer.print(", "); } writer.println(");"); } writer.println("}"); } catch (IOException e) { throw new RuntimeException(e); } finally { if (writer != null) { try { writer.close(); } catch (Throwable ex) { } } } } } } }
package annotations; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Set; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.AnnotationProcessorFactory; import com.sun.mirror.declaration.AnnotationTypeDeclaration; //每个annotation处理器类 需要有一个工厂类去创建它 public class InterfaceExtractorProcessorFactory implements AnnotationProcessorFactory { @Override public AnnotationProcessor getProcessorFor( Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment env) { return new InterfaceExtractorProcessor(env); } @Override public Collection<String> supportedAnnotationTypes() { return Collections.unmodifiableCollection(Arrays .asList("annotations.ExtractInterface")); } @Override public Collection<String> supportedOptions() { return Collections.emptySet(); } }
编译ExtractInterface.java
InterfaceExtractorProcessor.java
InterfaceExtractorProcessorFactory.java
最后执行
apt -factory annotations.InterfaceExtractorProcessorFactory annotations/Multiplier.java -s . //-s 表明将生成的源文件存放在哪里
--------------------------------------------------
将访问者模式应用到annotation处理上
package annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface DBTable { String value(); }
package annotations; 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.RUNTIME) public @interface Constraints { boolean primaryKey() default false; boolean allowNull() default true; boolean unique() default false; }
package annotations; 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.RUNTIME) public @interface SQLString { int value(); String name() default ""; Constraints constraints() default @Constraints; }
package annotations; 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.RUNTIME) public @interface SQLInteger { String name() default ""; Constraints constraints() default @Constraints; }
package annotations; @DBTable("t_member") public class Member { @SQLInteger(constraints = @Constraints(primaryKey = true)) private int id; @SQLString(value = 50, constraints = @Constraints(allowNull = false)) private String firstname; @SQLString(50) private String lastname; @SQLInteger private int age; @SQLString(name = "addr", value = 255) private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
package annotations; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Set; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.AnnotationProcessorFactory; import com.sun.mirror.declaration.AnnotationTypeDeclaration; import com.sun.mirror.declaration.ClassDeclaration; import com.sun.mirror.declaration.FieldDeclaration; import com.sun.mirror.declaration.TypeDeclaration; import com.sun.mirror.util.DeclarationVisitors; import com.sun.mirror.util.SimpleDeclarationVisitor; public class TableCreationProcessorFactory implements AnnotationProcessorFactory { @Override public AnnotationProcessor getProcessorFor( Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment env) { return new TableCreationProcessor(env); } @Override public Collection<String> supportedAnnotationTypes() { return Collections.unmodifiableCollection(Arrays.asList( "annotations.DBTable", "annotations.Constraints", "annotations.SQLString", "annotations.SQLInteger")); } @Override public Collection<String> supportedOptions() { return Collections.emptySet(); } private static class TableCreationProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env; private String sql = ""; private static String LINE_SEPARATOR = System .getProperty("line.separator"); public TableCreationProcessor(AnnotationProcessorEnvironment env) { this.env = env; } @Override public void process() { for (TypeDeclaration type : env.getSpecifiedTypeDeclarations()) { type.accept(DeclarationVisitors.getDeclarationScanner( new TableCreationVisitor(), DeclarationVisitors.NO_OP)); sql = sql.substring(0, sql.length() - LINE_SEPARATOR.length() - 1); sql += LINE_SEPARATOR + ")"; System.out.println("The creation sql is:\n" + sql); sql = ""; } } private class TableCreationVisitor extends SimpleDeclarationVisitor { @Override public void visitClassDeclaration(ClassDeclaration classdeclaration) { DBTable dbTable = classdeclaration.getAnnotation(DBTable.class); if (dbTable != null) { sql += "CREATE TABLE "; sql += (dbTable.value().length() < 1) ? classdeclaration .getSimpleName().toUpperCase() : dbTable.value(); sql += "(" + LINE_SEPARATOR; } } @Override public void visitFieldDeclaration(FieldDeclaration fielddeclaration) { String columnName = ""; if (fielddeclaration.getAnnotation(SQLString.class) != null) { SQLString sString = fielddeclaration .getAnnotation(SQLString.class); if (sString.name().length() < 1) columnName = fielddeclaration.getSimpleName() .toUpperCase(); else columnName = sString.name(); sql += "\t" + columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()) + "," + LINE_SEPARATOR; } if (fielddeclaration.getAnnotation(SQLInteger.class) != null) { SQLInteger sInteger = fielddeclaration .getAnnotation(SQLInteger.class); if (sInteger.name().length() < 1) columnName = fielddeclaration.getSimpleName() .toUpperCase(); else columnName = sInteger.name(); sql += "\t" + columnName + " INT" + getConstraints(sInteger.constraints()) + "," + LINE_SEPARATOR; } } private String getConstraints(Constraints constraints) { String result = ""; if (!constraints.allowNull()) result += " NOT NULL"; if (constraints.primaryKey()) result += " PRIMARY KEY"; if (constraints.unique()) result += " UNIQUE"; return result; } } } }
结果
发表评论
-
redis安装(windows.exe)
2014-05-21 22:54 743https://github.com/rgl/redis ... -
rabbitMQ安装(windows下)
2014-05-21 22:41 676进入项目下载主页面http://www.rabbitmq.co ... -
实现单线程的断点下载
2014-04-16 09:43 847/** * 实现单线程的断点下载 */ publ ... -
实现一个简易的http模拟器
2014-04-15 15:20 1811/** * http模拟器 * 模拟发送http请求和 ... -
xml学习鉴定
2014-04-09 23:33 846实现招生录取系统中的 ... -
xml学习
2014-04-08 22:47 1476XML:Extensible Markup Langu ... -
HTTP断点续传
2014-03-31 22:13 798http://fenglingcorp.iteye.com/b ... -
java多线程-线程状态转换
2014-03-01 09:20 8021. 新建(new):新创建了一个线程对象。 2. 可 ... -
跳过UTF-8的BOM
2014-02-14 12:19 1507/** version: 1.1 / 2007-01-25 ... -
java reference
2014-02-09 00:36 679import java.lang.ref.PhantomR ... -
不带头结点的单链表面试汇总
2014-01-24 13:47 1500import java.io.ByteArrayInputSt ... -
带头节点的单链表面试题汇总
2014-01-23 15:12 1033import java.io.ByteArrayInput ... -
单链表面试题之-链表反转
2014-01-15 22:43 1107单链表反转 -------------------- ... -
java单链表-带头结点和不带头结点单链表的简单实现
2014-01-14 23:41 4935带头结点的单链表实现 public class LinkedL ... -
ClassLoader
2013-11-08 15:57 914public class ClassLoaderTest { ... -
URL和URI
2013-11-08 13:48 518private static void getData ... -
i++和++i
2013-11-06 15:26 529// i = i++ 计算过程 // temp = i; ... -
java 继承 多态
2013-11-06 15:19 809/** 运行结果: A's constructor co ... -
sealing violation
2013-11-03 16:10 3148一般以下两种情况会触发sealing安全异常 1)当被密封(s ... -
hashmap分析
2013-10-30 15:20 695/** hashmap底层维护着一个entry数组,每 ...
相关推荐
@Target:用于描述注解的使用范围,如果自定义注解不存在@Target,则表示该注解可以使用在任何程序元素之上。接收参数ElementType,其值如下: /**接口、类、枚举、注解**/ ElementType.TYPE /**字段、枚举的常量**/...
本Demo着重讲解如何利用 Annotation Processing Tool(APT) 在编译期间处理源文件中的注解信息,而非在运行时通过反射来获取和处理。 APT是Java标准库的一部分,它允许开发者编写自定义的注解处理器,这些处理器在...
在Java 6.0及更高版本中,javac编译器已经支持自定义Annotation的处理。 三、Annotation的使用和处理 - Annotation的处理通常涉及到两个主要步骤:定义和解析。定义是创建Annotation类型,解析是通过Java反射API...
2. 自定义Annotation:自定义Annotation需要定义一个接口,这个接口就是Annotation类型。通过定义成员变量(通常带有默认值),可以为Annotation添加特定的元数据。自定义Annotation可以通过`@interface`关键字创建...
Java 提供了一个名为 “apt” (Annotation Processing Tool) 的工具,用于处理 Annotation。它可以在编译阶段扫描源代码中的 Annotation,并调用预先定义好的 Annotation 处理器来完成特定的任务,例如生成额外的...
5. **自定义Annotation**:从Java 6.0起,开发者可以创建自己的Annotation类型,定义特定的元信息。这使得开发人员能够创建特定于应用程序的Annotation,用于各种目的,如验证、持久化、事务管理等。 6. **...
自定义Annotation通常需要与Annotation处理器配合,如Java的Apt工具,它可以扫描源代码,根据Annotation执行相应操作,例如验证非空约束。 四、Annotation的应用场景 - **编译时检查**:如`@NonNull`可以提示...
2. **Annotation 处理工具**:Annotation Processing Tool (apt) 是一个用于处理 Annotation 的工具,它可以分析源代码中的 Annotation,并根据这些信息生成相应的代码或文件。 三、Annotation 使用方法 1. **类型...
APT全称为Annotation Processing Tool,是Android开发中用于处理注解(Annotation)的一种工具。它允许开发者在编译期间通过自定义注解处理器来生成源代码、XML文件或其他资源,从而简化了代码编写,提高了效率。在...
这些标准Annotation直接被javac支持,而自定义Annotation则需要相应的处理机制来解析和利用。 Annotation的定义涉及到新的语法,它们看起来像接口,但成员变量有限制。每个Annotation成员是一个无参数的方法,代表...
- `apt` 工具:在 JDK/bin 目录下,它可以扫描源代码中的 Annotation 并调用用户定义的 Annotation 处理器,执行特定任务,如验证、代码生成等。 总的来说,Java Annotation 提供了一种声明式编程的方式,使得...
而Ant-APT则是Ant的一个扩展库,用于支持 Annotation Processing Tool(APT),使得在Ant构建过程中能够方便地处理注解(Annotation)。本文将深入探讨Ant-APT库的原理、功能以及如何在项目中使用。 首先,Ant是...
自定义注解需要相应的处理器来处理,这通常通过Java的注解处理工具(Annotation Processing Tool, apt)或Java Compiler API实现。处理器会在编译时自动触发,解析注解并执行相应逻辑。 6. **注解的应用场景** - ...
APT(Annotation Processing Tool),注解处理工具,是Java提供的一种机制,用于在编译期间处理注解。当编译器遇到特定注解时,APT会触发自定义的处理器,这些处理器可以生成额外的源代码或者编译时需要的类文件,...
编译时处理通常通过Apt(Annotation Processing Tool)或者Android的Dagger、Butter Knife等库实现,它们在编译期间读取注解并生成相应的代码。运行时处理则需要确保注解的保留,因为Java默认情况下不会保存注解信息...
【标题】"View注入demo(模仿ButterKnife的APT方式)" 涉及的主要知识点是Android中的编程工具和注解处理技术,特别是APT(Annotation Processing Tool)和ButterKnife库的使用。APT允许开发者在编译时通过注解来生成...
在Android开发中,APT(Annotation Processing Tool)是一种编译时技术,它允许开发者在源代码中使用注解(Annotations),并自动生成相应的辅助类或代码。这种技术在提高代码的可维护性和模块化方面有着显著的优势...
此外,还可以使用Annotation Processing Tool (APT)在编译时处理注解,生成额外的源代码或类文件。 4. **保留策略**:注解可以在编译时、运行时或两者都被保留。保留策略通过`@Retention`注解指定,例如`...
APT(Android Annotation Processing Tool)是Android平台上的一个关键组件,它为开发者提供了强大的元数据处理能力。APT允许开发者定义自定义注解,并在编译时自动处理这些注解,生成额外的源代码、XML文件或者其他...