`
天使的左手
  • 浏览: 54086 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

apt处理自定义annotation

    博客分类:
  • java
阅读更多
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;
			}

		}
	}

}


结果

  • 大小: 36.3 KB
分享到:
评论

相关推荐

    java8源码-APTDemo:自定义AnnotationProcessor处理自己的Annotation

    @Target:用于描述注解的使用范围,如果自定义注解不存在@Target,则表示该注解可以使用在任何程序元素之上。接收参数ElementType,其值如下: /**接口、类、枚举、注解**/ ElementType.TYPE /**字段、枚举的常量**/...

    java注解解析

    APT(annotation processing tool)是一个命令行工具,它在编译期对源代码文件进行检测找出其中的annotation,然后使用自定义processor来处理annotation,如生成新的 Java 文件。

    Jersey-Gest:Jersey Java注释扩展,用于创建REST GETPOST方法

    以@RestClass注释的类在编译时由apt-maven-plugin处理,然后加载我们的自定义AnnotationProcessor来生成新的Java类。 这个新类包含一个GET和POST方法,该方法调用以@RestMethod注释的我们的方法。

    ProcessorAnnotation

    完整的Android自定义注解demo项目,演示了自定义绑定view,activity方法的初始化操作等

    Adapter实现自定义数据类型student

    自定义Adapter: import android.annotation.SuppressLint; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android....

    Android自定义processor实现bindView功能的实例

    编译时注解的核心依赖APT(Annotation Processing Tools)实现,原理是在某些代码元素上(如类型、函数、字段等)添加注解,在编译时编译器会检查AbstractProcessor的子类,并且调用该类型的process函数,然后将添加了...

    emergen:基于Java APT的紧急设计生成器框架

    emergen-core提供了可与APT和不同模板引擎一起使用的基类,因此您可以轻松实现自己的自定义注释处理器。 出现emergen-freemarker和emergen-velocity模块为两个流行的开源模板引擎提供了服务提供者实现,您可以使用...

    java7hashmap源码-ButterKnifeSample:ButterKnife最简实现。撸一个最简单的View注解工具!单libra

    近来研究APT(Annotation Processing Tool)技术的实现场景和实际应用,想到可以先了解一下APT技术应用的先驱框架们。最具代表性的就是。 网络上大多数介绍ButterKnife简单实现的例子都写得很繁琐, 非要区分compiler、...

    疯狂JAVA讲义

    10.4.2 自定义异常类 371 10.4.3 catch和throw同时使用 371 10.4.4 异常链 373 10.5 Java的异常跟踪栈 374 10.6 异常处理规则 376 10.6.1 不要过度使用异常 377 10.6.2 不要使用过于庞大的try块 378 10.6.3 ...

    java8源码-somethingnew:各种演示在这里

    stn-annotation 基于spring-aop实现的bean注册,注入与管理。。。很蠢, 简单实现IOC功能 主要涉及反射与自定义注解的使用 @Bean 用于对象的自动创建 @Autowired 用于自动注入 Aware接口 用于在创建对象时候自动调用...

    BRouter

    简介 BRouter是一个Kotlin编写的面向模块Android路由库,支持: 路由 泛平台路由定义 ... annotationProcessor " com.bilibili.android:brouter-apt: $b router_version " // or kapt for Kotlin impleme

    J2SE技术总结-Java学习精华教程-电子书

    ..........apt.exe(注解处理工具) .....Java语法入门 ..........概述 ..........变量与数据类型 ..........标识符 ..........运算符 ..........控制台输入输出 ..........流程控制 ..........数组的使用 .....字符串...

Global site tag (gtag.js) - Google Analytics