package com.luban.proxy;
import com.luban.jdk动态代理.Invocation;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class MySelfProxyUtilForJDK {
/**
package com.cjf.proxy;
import com.luban.dao.动态代理.LubanDao;
import com.luban.jdk动态代理.Invocation;
public class Result implements LubanDao {
private Invocation invocation;
public Result(Invocation invocation) {
this.invocation = invocation;
}
public void query() {
Mehtod method = Class.forName("LubanDao").getDeclaredMethod("query");
invocation.invoke(this,method,Object[]{});
}
public String quert(String str,int i,testModel i) {
Mehtod method = Class.forName("LubanDao").getDeclaredMethod("quert");
int argsNum = 拿到参数的个数
Object[] args = new Object[argsNum];
for(){
把所有参数拼接args中
}
return (String)invocation.invoke(this,method,Object[]{str,});
}
}
*/
public static Object newInstance(Object target,Invocation invocation){
Object proxy = null;
Class inter = target.getClass().getInterfaces()[0];
String InvocationInterName = invocation.getClass().getSimpleName();
String InterName = inter.getSimpleName();
Method[] methods = inter.getMethods();
String line = "\n";
String tab = "\t";
String packageName = "package com.cjf.proxy;"+line;
String importClass = "import "+inter.getName()+";"+line;
importClass += "import "+invocation.getClass().getName()+";"+line;
importClass += "import java.lang.reflect.Method;"+line;
String clazzFirstLineContent = " public class $proxy implements "+InterName+" {"+line;
String filedContent = tab+"private "+InvocationInterName+" invocation;"+line;
String ConsturctContent = tab+"public $proxy("+InvocationInterName+" invocation){"+line;
String ConsturctContentTwo = tab+tab+"this.invocation=invocation;"+line;
String ConsturctContentThree = tab+"}"+line;
String ConsturctContentResult = ConsturctContent+ConsturctContentTwo+ConsturctContentThree;
String method = "";
String result = "";
if(methods!=null&&methods.length>0){
for(Method OneMethod:methods){
String MethodName = OneMethod.getName(); // 拿到方法名
String ReturnName = OneMethod.getReturnType().getSimpleName(); // 拿到return的类型
Class[] Parameters = OneMethod.getParameterTypes(); // 拿到参数列表
String ParameterStr = "";//拼接方法的参数
// 拿method必须加入一个参数类型判断,防止重载方法的干扰
String methodArgs = "new Class[]{";
if(Parameters!=null&&Parameters.length>0){
for (Class OneParameter : Parameters) {
methodArgs+=OneParameter.getSimpleName()+".class,";
}
}
if(Parameters!=null&&Parameters.length>0&&!methodArgs.equals("new Class[]{")){
methodArgs=methodArgs.substring(0,methodArgs.lastIndexOf(","));
}
methodArgs+="}";
String MethodForInvocation = tab+tab+"Method method = Class.forName(\""+inter.getName()+"\")."+
"getDeclaredMethod(\""+MethodName+"\","+methodArgs+");"+line;
// 构造一个object数组
String ObjectArgs = "";
int flag = 0;
if(Parameters!=null&&Parameters.length>0) {
for (Class OneParameter : Parameters) {
importClass += "import " + OneParameter.getName() + ";" + line;
ParameterStr += OneParameter.getSimpleName() + " p" + flag + ",";
flag++;
}
}
ObjectArgs = tab+tab+"Object[] args = new Object["+flag+"];"+line;
for(int i=0;i<flag;i++){
ObjectArgs += tab+tab+"args["+i+"]=p"+i+";"+line;
}
if (Parameters.length>0){
ParameterStr=ParameterStr.substring(0,ParameterStr.lastIndexOf(","));
}
// 构造方法签名
String OneMethodStr = tab+"public "+ReturnName+" "+MethodName+" ("+
ParameterStr+") throws Exception {"+line;
String OneMethodStrBody2 = tab+tab+"";
if(!"void".equals(ReturnName)){
OneMethodStrBody2 += "return ("+ReturnName+")";
}
OneMethodStrBody2 += "invocation.invoke(this,method,args);"+line;
String OneMethodStrBody3 = tab+"}"+line;
//
method+=OneMethodStr+
MethodForInvocation+
ObjectArgs+
OneMethodStrBody2+
OneMethodStrBody3;
}
}
result = packageName+importClass+clazzFirstLineContent+filedContent+ConsturctContentResult+method+"}"+line;
File file = new File("D:\\com\\cjf\\proxy\\$proxy.java");
try{
if(!file.exists()){
file.createNewFile();
}else{
file.delete();
file.createNewFile();
}
FileWriter fw = new FileWriter(file);
fw.write(result);
fw.flush();
fw.close();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(file);
JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
URL[] urls = new URL[]{new URL("file:D:\\\\")};
URLClassLoader urlClassLoader = new URLClassLoader(urls);
Class clazz = urlClassLoader.loadClass("com.cjf.proxy.$proxy");
Constructor constructor = clazz.getConstructor(invocation.getClass());
proxy = constructor.newInstance(invocation);
}catch (Exception e){
e.printStackTrace();
}
return proxy;
}
}
最终生成的代理类:
package com.cjf.proxy;
import com.luban.dao.动态代理.LubanDao;
import com.luban.jdk动态代理.InvocationImple;
import java.lang.reflect.Method;
import java.lang.String;
import java.lang.Integer;
import com.luban.app.testModel;
public class $proxy implements LubanDao {
private InvocationImple invocation;
public $proxy(InvocationImple invocation){
this.invocation=invocation;
}
public void query () throws Exception {
Method method = Class.forName("com.luban.dao.动态代理.LubanDao").getDeclaredMethod("query",new Class[]{});
Object[] args = new Object[0];
invocation.invoke(this,method,args);
}
public String quert (String p0,Integer p1,testModel p2) throws Exception {
Method method = Class.forName("com.luban.dao.动态代理.LubanDao").getDeclaredMethod("quert",new Class[]{String.class,Integer.class,testModel.class});
Object[] args = new Object[3];
args[0]=p0;
args[1]=p1;
args[2]=p2;
return (String)invocation.invoke(this,method,args);
}
}
用户实现aop逻辑的类:
package com.luban.jdk动态代理;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public interface Invocation {
public Object invoke(Object proxy,Method method,Object[] args) throws InvocationTargetException, IllegalAccessException;
}
package com.luban.jdk动态代理;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class InvocationImple implements Invocation{
private Object target ;
public InvocationImple(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("这是我的apo逻辑");
return method.invoke(target,args);
}
}
目标对象:
package com.luban.dao.动态代理;
import com.luban.app.testModel;
public interface LubanDao {
public void query() throws Exception;
public String quert(String str,Integer i,testModel testModel) throws Exception ;
}
package com.luban.dao.动态代理;
import com.luban.app.testModel;
public class LubanDaoImpl implements LubanDao{
public void query(){
System.out.println("query");
}
public String quert(String str,Integer i,testModel testModel) {
System.out.println("this is query"+str+" "+i+" "+testModel.getTest());
return str;
}
}