文档章节

Java动态实现接口逻辑,不用写实现类

wx9944
 wx9944
发布于 2016/08/13 23:07
字数 745
阅读 303
收藏 0
点赞 0
评论 0

` package orm.util;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import orm.annotation.sql.Delete;
import orm.annotation.sql.Insert;
import orm.annotation.sql.Select;
import orm.annotation.sql.Update;
import orm.dao.StudentDao;



public class Impl {
	public static void main(String[] args) throws Exception {
		long start=System.currentTimeMillis();
		//第一个参数:自定义生成类的名字;第二个参数:继承的接口
		StudentDao dao=(StudentDao) getDao("StudentDaoImpl", "orm.dao.StudentDao");
		System.out.println("生成字节码:"+(System.currentTimeMillis()-start));
		
		
	}
	
	/**
	 * 获取方法注解上面的SQL
	 * [@param](http://my.oschina.net/u/2303379) method
	 * [@return](http://my.oschina.net/u/556800)
	 */
	private static Object getMethodAnnotation(Method method){
		Object annotation=null;
		String sql="";
		if(method.isAnnotationPresent(Select.class)){
			annotation=method.getAnnotation(Select.class);
			sql=((Select) annotation).value();
		}else if(method.isAnnotationPresent(Insert.class)){
			annotation=method.getAnnotation(Insert.class);
			sql=((Insert) annotation).value();
		}else if(method.isAnnotationPresent(Update.class)){
			annotation=method.getAnnotation(Update.class);
			sql=((Update) annotation).value();
		}else if(method.isAnnotationPresent(Delete.class)){
			annotation=method.getAnnotation(Delete.class);
			sql=((Delete) annotation).value();
		}
		System.out.println("getMethodAnnotation方法获取注解的值:"+sql);
		return annotation;
	}
//	private static String getClassName(String className){
//		//1.找到空格的下标
//		int index=className.indexOf(" ");
//		//2.截取字符串
//		String str=className.substring(0, index+2);
//		System.out.println(str);
//		return "";
//	}
	
	
	
	/**
	 * 传入类信息,获取方法的拼接逻辑,并返回方法拼接后的字符串
	 * [@param](http://my.oschina.net/u/2303379) c
	 * [@return](http://my.oschina.net/u/556800)
	 */
	private static String getMethodStrs(Class c){
		Method[] methods=c.getDeclaredMethods();
		//定义方法字符串
		String methodStr="";
		//获取方法信息
		for(Method method:methods){
			methodStr = getMethodStr(methodStr, method);
		}
		return methodStr;
	}

	/**
	 * 传入方法参数,拼接方法名
	 * [@param](http://my.oschina.net/u/2303379) methodStr
	 * @param method
	 * @return
	 */
	private static String getMethodStr(String methodStr, Method method) {
		//获取方法名
		String methodName=method.getName();
		
		//获取返回值类型
		String returnTypeName=method.getReturnType().getName();
		
		//获取参数集合
		String parameterName="";
		Class[] classes =method.getParameterTypes();
		
		//拼接参数的字符串
		if(classes.length!=0&&classes!=null){
			for(int i=0;i<classes.length;i++){
				parameterName+=(classes[i].getName()+" "+(char)(i+97)+",");
			}
			parameterName=parameterName.substring(0, parameterName.length()-1);
		}
		
		//执行方法体
		String methodBody="System.out.println(\"执行方法:\"+\""+methodName+"\");";
		
		//方法结尾
		String methodEnd="";
		if(!returnTypeName.equals("void")){
			methodEnd="return null;";
		}
		methodStr+=
			"public "+returnTypeName+" "+methodName+"("+parameterName+"){" +
				methodBody + methodEnd+
			"}";
		return methodStr;
	}
	
	
	
	
	/**
	 * 获取dao对象
	 * @param implName 继承的对象
	 * @param daoInterface dao接口的位置信息
	 * @return
	 */
	public static Object getDao(String implName,String daoInterface) {
		Class interfaceClass=null;
		try {
			interfaceClass=Class.forName(daoInterface);
		} catch (ClassNotFoundException e2) {
			e2.printStackTrace();
		}
		
		//Java 源代码
		String sourceStr=
			"public class "+implName+" implements "+daoInterface+"{ " +
				getMethodStrs(interfaceClass)+
			"}";
		// 类名及文件名
		String clsName = implName;
		// 方法名
		//String methodName = "findAll";
		// 当前编译器
		JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();
		//Java 标准文件管理器
		StandardJavaFileManager fm = cmp.getStandardFileManager(null,null,null);
		//Java 文件对象
		JavaFileObject jfo = (JavaFileObject) new StringJavaObject(clsName,sourceStr);
		//JavaFileObject jfo1 = (JavaFileObject) new StringJavaObject("hello",sourceStr);
		// 编译参数,类似于javac <options> 中的options
		List<String> optionsList = new ArrayList<String>();
		// 编译文件的存放地方,注意:此处是为Eclipse 工具特设的
		optionsList.addAll(Arrays.asList("-d","./bin"));
		// 要编译的单元
		List<JavaFileObject> jfos = Arrays.asList(jfo);
		// 设置编译环境
		JavaCompiler.CompilationTask task = cmp.getTask(null, fm, null,optionsList,null,jfos);
		// 编译成功
		if(task.call()){
			// 生成对象
			try {
				Object obj = Class.forName(clsName).newInstance();
				Class<? extends Object> cls = obj.getClass();
				return obj;
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			}
		}
		
		return null;
	}
}
// 文本中的Java 对象
class StringJavaObject extends SimpleJavaFileObject{
	// 源代码
	private String content = "";
	// 遵循Java 规范的类名及文件
	public StringJavaObject(String _javaFileName,String _content){
		super(_createStringJavaObjectUri(_javaFileName),Kind.SOURCE);
		content = _content;
	}
	// 产生一个URL 资源路径
	private static URI _createStringJavaObjectUri(String name){
		// 注意此处没有设置包名
		return URI.create("String:///" + name + Kind.SOURCE.extension);
	}
	// 文本文件代码
	public CharSequence getCharContent(boolean ignoreEncodingErrors)
	throws IOException {
		return content;
	}
}`

© 著作权归作者所有

共有 人打赏支持
wx9944
粉丝 0
博文 7
码字总数 1526
作品 0
青岛
Python和Java的硬盘夜话

点击上方“程序员小灰”,选择“置顶公众号” 有趣有内涵的文章第一时间送达! 本文转载自公众号 码农翻身 这是一个程序员的电脑硬盘,在一个叫做“学习”的目录下曾经生活着两个小程序,一个...

bjweimengshu ⋅ 05/16 ⋅ 0

Spring AOP切点表达式详解

简介 面向对象编程,也称为OOP(即Object Oriented Programming)最大的优点在于能够将业务模块进行封装,从而达到功能复用的目的。通过面向对象编程,不同的模板可以相互组装,从而实现更为...

张旭峰 ⋅ 06/05 ⋅ 2

SWIG与JAVA 交互最全开发指南一

项目背景 最近开始研究做移动端项目,但是本人基本是做了五六年的c++的底层研发,对C++的研发可以说是驾轻就熟了,但是对于android还是属于刚入门阶段,虽然断断续续做移动端也做了一年,但是...

揽月凡尘 ⋅ 06/16 ⋅ 0

2018年Java编程学习面试最全知识点总结

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰 ⋅ 05/14 ⋅ 0

mybatis系统学习(二)——使用基础mybatis代替原始jdbc

mybatis系统学习(二)——使用基础mybatis代替原始jdbc 前言 这一篇笔记的内容应当是建立在上一篇的基础之上,不论是使用的数据表,还是对应的实体类,都在上一篇有过说明。 有兴趣的或者对...

推荐码发放 ⋅ 05/03 ⋅ 0

java开发中的常用的设计模式

设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代...

qq_38024548 ⋅ 05/28 ⋅ 0

Java开发每日复盘2018_0514

今天主要跟大家分享3个部分: 一、「Java的核心机制」 二、「Java命名规范」 三、「Java数据类型相关」 下面我们来一个一个的说: 「Java核心机制」 Java是一种强制面向对象的解释型语言(O...

ZeroOSTalk ⋅ 05/14 ⋅ 0

Java 5 、6、 7中新特性

JDK5新特性(与1.4相比)【转】 1 循环 for (type variable : array){ body} for (type variable : arrayList){body} 而1.4必须是: for (int i = 0; i < array.length; i++){ type variabl......

thinkyoung ⋅ 2014/10/14 ⋅ 0

类加载器ClassLoader-1

一, 类加载器深入剖析 1,Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机将结束生命周期: –执行了System.exit()方法 –程序正常执行结束 –程序在执行过程中遇到了异常或错误而...

康熙兄弟 ⋅ 06/02 ⋅ 0

【JVM】 java内存区域与内存溢出异常

前言 此系列博客是读《深入理解java虚拟机》所做的笔记整理。 No1. JVM内存管理这堵墙? 对C和C++的开发人员来说,在内存管理领域,他们既拥有每一个对象的“所有权”,也担负着每一个对象生...

binggetong ⋅ 05/07 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Gitee 生成并部署SSH key

1.如何生成ssh公钥 你可以按如下命令来生成 sshkey: ssh-keygen -t rsa -C "xxxxx@xxxxx.com" # Generating public/private rsa key pair...# 三次回车即可生成 ssh key 查看你的 ...

晨猫 ⋅ 26分钟前 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

一起读书《深入浅出nodejs》-node模块机制

node 模块机制 前言 说到node,就不免得提到JavaScript。JavaScript自诞生以来,经历了工具类库、组件库、前端框架、前端应用的变迁。通过无数开发人员的努力,JavaScript不断被类聚和抽象,...

小草先森 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部