模仿jdk动态代理


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;
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值