文档章节

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

wx9944
 wx9944
发布于 2016/08/13 23:07
字数 745
阅读 335
收藏 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
青岛
Java拾遗:007 - 代理模式与动态代理

代理模式 在日常开发中我们可以会接手一些老的项目,有时连源码都没有,或者有时候我会需要对业务逻辑做一定增强(功能扩展,如:日志、事务等),这时候我们通常不能或者不建议直接修改源码...

一别丶经年
08/04
0
0
动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码。当前有很多开源框架可以完成这些功能,如ASM,Javassist。 动态代理机制详解(JDK 和CGLIB,Javassist,ASM...

素雷
2017/10/19
0
0
wenweihu86/raft-java

raft-java Raft implementation library for Java. 参考自Raft论文和Raft作者的开源实现LogCabin。 支持的功能 leader选举 日志复制 snapshot 集群成员动态更变 Quick Start 在本地单机上部署...

wenweihu86
07/01
0
0
分布式一致性算法raft的java实现 - raft-java

raft-java Raft implementation library for Java. 参考自Raft论文和Raft作者的开源实现LogCabin。 支持的功能 leader选举 日志复制 snapshot 集群成员动态更变 Quick Start 在本地单机上部署...

wenweihu86
07/01
0
0
JAVA代理模式与动态代理模式

1、代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介...

lee123lee
2013/08/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

搬瓦工镜像站bwh1.net被DNS污染,国内打不开搬瓦工官网

今天下午(2018年10月17日),继搬瓦工主域名bandwagonhost.com被污染后,这个国内的镜像地址bwh1.net也被墙了。那么目前应该怎么访问搬瓦工官网呢? 消息来源:搬瓦工优惠网->搬瓦工镜像站b...

flyzy2005
51分钟前
1
0
SpringBoot自动配置

本篇介绍下,如何通过springboot的自动配置,将公司项目内的依赖jar,不需要扫描路径,依赖jar的情况下,就能将jar内配置了@configuration注解的类,创建到IOC里面 介绍下开发环境 JDK版本1.8 spr...

贺小五
今天
3
0
命令行新建Maven多项目

参考地址 # DgroupId 可以理解为包名# DartifactId 可以理解为项目名mvn archetype:generate -DgroupId=cn.modfun -DartifactId=scaffold -DarchetypeArtifactId=maven-archetype-quickst......

阿白
今天
1
0
OSChina 周四乱弹 —— 上帝对我单身年限的惩罚越来越长了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @达尔文:分享张卫健的单曲《身体健康》 《身体健康》- 张卫健 手机党少年们想听歌,请使劲儿戳(这里) 昨天是重阳节咯, 可惜小小编辑总是晚...

小小编辑
今天
12
1
django rest framework 外键序列化方法与问题总结

django rest framework 外键序列化方法与问题总结 当借口中需要出现一对多关系的时候,我们可以用rest_framwork的序列化功能来处理,代码如下. # models.pyfrom django.db import modelscl...

_Change_
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部