设计模式四:代理模式(Proxy pattern)

目录

相关视频:

相关文章:

1、代理模式基本概念及分类

1.1、代理模式定义:

1.2、几种常见的代理模式:

2、静态代理和动态代理

2.1、静态代理

2.1.1、定义

 2.1.2、代码实战:

2.2、动态代理

2.2.1、用JDK来实现动态代理

2.2.2、JDK动态代理和CGLIB动态代理的区别

3、模拟JDK动态代理实现思路分析及简单实现

3.1、初步实现

3.1.1、Car.java

3.1.2、Moveable.java

3.1.3、CarTimeProxy.java

3.1.4、Proxy.java

3.1.5、Client.java

3.1.6、 Proxy.java

3.2、完善动态代理实现

3.2.1、Proxy.java

3.2.2、Client.java

3.2.3、$Proxy0.java

3.2.4、目录结构

3.3、动态代理实现添加InvocationHandler

3.3.1、InvocationHandler.java

3.3.2、TimeHandler.java

3.3.3、Proxy.java

3.3.4、Client.java


相关视频:

模式的秘密---代理模式

java设计模式23种设计模式视频(第13~15章代理模式 复合模式 桥接模式)

相关文章:

第一推荐:轻松学,Java 中的代理模式及动态代理

第二推荐:10分钟看懂动态代理设计模式

1、代理模式基本概念及分类

1.1、代理模式定义:

为其他对象提供一种代理,以控制对这个对象的访问。代理对象起到中介作用,可以去掉功能服务或增加额外的服务。
    举例:火车购票,可以去直接去火车站也可以去代售点,这个代售点就可以称之为火车站的代理。而代售点除了卖火车票外,可能会有自己额外的服务,比如电话预约。同时,代售点是不能退火车票的,要退的话只能去火车站。这个代售点,少了一些功能服务(退票),增加了一些额外服务(电话预约)。

1.2、几种常见的代理模式:

远程代理:为不同地理的对象,提供局域网代表对象。类似于客户端-服务器的模式。

举例:我有一家连锁店,我想实时了解各个门店的销售信息,我们可以通过远程代理来构造各个门店的监视器,来随时报告各个门店的销售和库存信息。

虚拟代理:根据需要将资源消耗很大的对象进行延迟,真正需要的时候进行创建。

举例:我们在浏览一个新闻的时候,会有文字和图片,如果网络情况不好,我们可以使用虚拟代理,用一个本地的图片暂时替代我们要加载的图片,当图片获取成功后再展示出来,如图二所示。这就是虚拟代理的一个简单应用。

图一:

图二:

保护代理:权限控制。例如,有些网站,只有注册登陆后才能发帖、评论。

智能引用代理:刚才举的火车票代售点的例子。

2、静态代理和动态代理

2.1、静态代理

2.1.1、定义

静态代理:代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。

 2.1.2、代码实战:

我们用代码来实现车行驶。

2.1.2.1、常规方式

Moveable.java

public interface Moveable {
    void move();
}

Car.java

public class Car implements Moveable {


    /**
     * 如果不使用代理模式的话,我们如果想记录车行驶的时间,会采用如下方式
     */
    @Override
    public void move() {

        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");
        // 实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("汽车结束行驶... ");
        System.out.println("汽车行驶时间为:" + time + "毫秒");
    }


}

Client.java

/**
 * 测试类
 */
public class Client {
    public static void main(String[] args) {
        // 不使用代理模式,常规方式
        Car car = new Car();
        car.move();
    }
}

 打印结果为:

2.1.2.2、通过继承的方式实现

Car.java

public class Car implements Moveable {
    @Override
    public void move() {
        // 实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Car2.java

public class Car2 extends Car {
    @Override
    public void move() {
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        // 调用父类 Car 的方法 move()
        super.move();

        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("汽车结束行驶... ");
        System.out.println("汽车行驶时间为:" + time + "毫秒");
    }
}

Client.java

public class Client {
    public static void main(String[] args) {
        // 使用继承的方式
        Moveable moveable = new Car2();
        moveable.move();
    }
}

 打印结果为:

 2.1.2.3、通过聚合的方式实现

聚合:简单理解就是在一个类中调用另一个类的对象。

Car3.java

public class Car3 implements Moveable {

    private Car car;

    // 通过构造方法 把 Car 传进来
    public Car3(Car car) {
        this.car = car;
    }

    @Override
    public void move() {
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        car.move();

        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("汽车结束行驶... ");
        System.out.println("汽车行驶时间为:" + time + "毫秒");
    }

}

Clien.java

public class Client {
    public static void main(String[] args) {
        // 不使用代理模式,常规方式
//        Car car = new Car();
//        car.move();

        // 使用继承的方式
//        Moveable moveable = new Car2();
//        moveable.move();

        // 使用聚合的方式
        Car car = new Car();
        Car3 car3 = new Car3(car);
        car3.move();

    }
}

打印结果不变。

以上我们通过继承和聚合两种方式来实现静态代理,那么哪种方式更适合静态代理呢?

我们分析一下,先来说继承这种方式,现在如果需求发生变化,我们就得新建一个子类,如下图:

很显然,这种方式会随着功能的增加而变得越来越臃肿,因此这种方式应该被排除!

那么,聚合的方式呢?

CarTimeProxy.java

public class CarTimeProxy implements Moveable {

    private Moveable moveable;

    public CarTimeProxy(Moveable moveable) {
        this.moveable = moveable;
    }

    @Override
    public void move() {
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        moveable.move();

        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("汽车结束行驶... ");
        System.out.println("汽车行驶时间为:" + time + "毫秒");
    }
}

CarLogProxy.java

public class CarLogProxy implements Moveable {

    private Moveable moveable;

    public CarLogProxy(Moveable moveable) {
        this.moveable = moveable;
    }

    @Override
    public void move() {
        System.out.println("日志开始...");
        moveable.move();
        System.out.println("日志结束...");
    }
}

Client.java

public class Client {
    public static void main(String[] args) {
        // 不使用代理模式,常规方式
//        Car car = new Car();
//        car.move();

        // 使用继承的方式
//        Moveable moveable = new Car2();
//        moveable.move();

        // 使用聚合的方式
//        Car car = new Car();
//        Car3 car3 = new Car3(car);
//        car3.move();

        //先记录日志,再记录时间
        Car car = new Car();
        CarTimeProxy carTimeProxy = new CarTimeProxy(car);
        CarLogProxy carLogProxy = new CarLogProxy(carTimeProxy);
        carLogProxy.move();

    }
}

打印结果为:

如果我们想先记录时间再记录日志呢?很简单:

Client.java

public class Client {
    public static void main(String[] args) {
        // 不使用代理模式,常规方式
//        Car car = new Car();
//        car.move();

        // 使用继承的方式
//        Moveable moveable = new Car2();
//        moveable.move();

        // 使用聚合的方式
//        Car car = new Car();
//        Car3 car3 = new Car3(car);
//        car3.move();

        //先记录日志,再记录时间
//        Car car = new Car();
//        CarTimeProxy carTimeProxy = new CarTimeProxy(car);
//        CarLogProxy carLogProxy = new CarLogProxy(carTimeProxy);
//        carLogProxy.move();

        //先记录时间,再记录日志
        Car car = new Car();
        CarLogProxy carLogProxy = new CarLogProxy(car);
        CarTimeProxy carTimeProxy = new CarTimeProxy(carLogProxy);
        carTimeProxy.move();
    }
}

打印结果为:

可以看到,使用聚合的方式会比使用继承的方式灵活很多。

那么,接下来,如果我们需要给火车加上行驶时间和日志的记录呢?我们是否需要再新建两个代理类?有没有更简单的方法呢?

那么,有没有一种方法能够动态产生代理,实现对不同类、不同方法的代理呢?下面我们来了解一下动态代理。

2.2、动态代理

2.2.1、用JDK来实现动态代理

我们先来了解一下JDK的动态代理:

图一:

图二:

下面通过代码来了解一下:

TimeHandler.java

/**
 * InvocationHandler 事务处理器
 */
public class TimeHandler implements InvocationHandler {

    private Object target;

    public TimeHandler(Object target) {
        this.target = target;
    }

    /**
     * @param proxy  被代理的对象
     * @param method 被代理的对象的方法
     * @param args   被代理的对象的方法的参数
     * @return       所调用方法的返回值
     * @throws Throwable 异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        method.invoke(target);

        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("汽车结束行驶... ");
        System.out.println("汽车行驶时间为:" + time + "毫秒");

        return null;
    }

}

Test.java

public class Test {
    public static void main(String[] args) {
        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class<?> cls = car.getClass();
        /**
         * newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
         * loader: 被代理类的类加载器
         * interfaces: 我们要实现的接口
         * h:事务处理器
         */
        Moveable m =  (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
        m.move();
    }
}

打印结果:

总结:

动态代理实现步骤:

作业,实现时间记录和日志记录:

public class Test {
    public static void main(String[] args) {

//        timeTest();
//        logTest();

        timeAndLogTest();

    }

    private static void timeAndLogTest() {
        Car car = new Car();

        InvocationHandler timeHandler = new TimeHandler(car);
        Class<?> cls = car.getClass();
        Moveable moveable = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),
                cls.getInterfaces(), timeHandler);

        InvocationHandler logHandler = new LogHandler(moveable);
        Class<?> class2 = moveable.getClass();
        Moveable moveable2 = (Moveable) Proxy.newProxyInstance(class2.getClassLoader(),
                class2.getInterfaces(), logHandler);

        moveable2.move();
    }

    private static void logTest() {
        Car car = new Car();
        InvocationHandler logHandler = new LogHandler(car);
        Class<?> cls = car.getClass();

        Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),
                cls.getInterfaces(), logHandler);
        m.move();
    }

    private static void timeTest() {
        Car car = new Car();
        InvocationHandler timeHandler = new TimeHandler(car);
        Class<?> cls = car.getClass();
        /**
         * newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
         * loader: 被代理类的类加载器
         * interfaces: 我们要实现的接口
         * h:事务处理器
         */
        Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),
                cls.getInterfaces(), timeHandler);
        m.move();
    }
}

2.2.2、JDK动态代理和CGLIB动态代理的区别

CglibProxy.java
package com.ph.proxy.cglibProxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxy implements MethodInterceptor {

    private Enhancer enhancer=new Enhancer();

    public Object getProxy(Class clazz){
        // 设置创建子类的类
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     * 拦截所有目标类方法的调用
     * @param o 目标类的实例
     * @param method 目标方法的反射对象
     * @param objects 方法的参数
     * @param methodProxy 代理类的实例
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects,
                            MethodProxy methodProxy) throws Throwable {
        System.out.println("日志开始...");
        //代理类调用父类的方法
        methodProxy.invokeSuper(o,objects);
        System.out.println("日志结束...");
        return null;
    }
}
Train.java
package com.ph.proxy.cglibProxy;

public class Train {
    public void move(){
        System.out.println("train running...");
    }
}
Client.java
package com.ph.proxy.cglibProxy;

public class Client {

    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        Train train = (Train) proxy.getProxy(Train.class);
        train.move();
    }

}

3、模拟JDK动态代理实现思路分析及简单实现

动态代理实现思路
实现功能:通过Proxy的newProxyInstance返回代理对象
1、声明一段源码(动态产生代理)
2、编译源码(JDK Compiler API),产生新的类(代理类)
3、将这个类load到内存中,产生一个新的对象(代理对象)
4、return 代理对象

3.1、初步实现

3.1.1、Car.java

package com.test.proxy;

import java.util.Random;

public class Car implements Moveable {

    @Override
    public void move() {
        // 实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

3.1.2、Moveable.java

package com.test.proxy;

public interface Moveable {
    void move();
}

3.1.3、CarTimeProxy.java

package com.test.proxy;


public class CarTimeProxy implements Moveable {

    private Moveable moveable;

    public CarTimeProxy(Moveable moveable) {
        this.moveable = moveable;
    }

    @Override
    public void move() {
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        moveable.move();

        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("汽车结束行驶... ");
        System.out.println("汽车行驶时间为:" + time + "毫秒");
    }
}

3.1.4、Proxy.java

package com.test.proxy;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class Proxy {


    public static Object newInstance() {

        String str = "package com.test.proxy;\n" +
                "\n" +
                "public class $Proxy0 implements Moveable {\n" +
                "\n" +
                "    private Moveable moveable;\n" +
                "\n" +
                "    public $Proxy0(Moveable moveable) {\n" +
                "        this.moveable = moveable; \n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public void move() {\n" +
                "        long startTime = System.currentTimeMillis();\n" +
                "        System.out.println(\"汽车开始行驶...\");\n" +
                "\n" +
                "        moveable.move();\n" +
                "\n" +
                "        long endTime = System.currentTimeMillis();\n" +
                "        long time = endTime - startTime;\n" +
                "        System.out.println(\"汽车结束行驶... \");\n" +
                "        System.out.println(\"汽车行驶时间为:\" + time + \"毫秒\");\n" +
                "    }\n" +
                "}";

        /**
         * System.getProperty("user.dir")  -- D:\idea_ws\java\ProxyTest1
         *
         */
        String fileName = System.getProperty("user.dir") + "/bin/com/test/proxy/$Proxy0.java";
//        System.out.println(fileName);

        File file = new File(fileName);
        try {
            FileUtils.writeStringToFile(file, str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

}

3.1.5、Client.java

package com.test.proxy;

/**
 * 测试类
 */
public class Client {


    public static void main(String[] args) {
        Proxy.newInstance();
    }


}

3.1.6、 Proxy.java

以上只是初步实现,但是我们的目标是对任意对象的任意方法产生任意代理,所以还需要继续改造。

package com.test.proxy;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;

public class Proxy {


    public static Object newInstance(Class interfa) {
        String rt = "\r\n";
        String methodStr = "";
        for (Method m : interfa.getMethods()) {
            methodStr += "	@Override" + rt +
                    "	public void " + m.getName() + "() {" + rt +
                    "		long starttime = System.currentTimeMillis();" + rt +
                    "		System.out.println(\"汽车开始行驶....\");" + rt +
                    "		m." + m.getName() + "();" + rt +
                    "		long endtime = System.currentTimeMillis();" + rt +
                    "		System.out.println(\"汽车结束行驶....  汽车行驶时间:\" " + rt +
                    "				+ (endtime - starttime) + \"毫秒!\");" + rt +
                    "	}";
        }

        String str = "package com.test.proxy;\n" +
                "\n" +
                "public class $Proxy0 implements " + interfa.getName() + "{\n" +
                "\n" +
                "    private " + interfa.getName() + " m;\n" +
                "\n" +
                "    public $Proxy0(" + interfa.getName() + " m) {\n" +
                "		super();" + rt +
                "        this.m = m; \n" +
                "    }" + rt +
                methodStr + rt +
                "}";

        /**
         * System.getProperty("user.dir")  -- D:\idea_ws\java\ProxyTest1
         *
         */
        String fileName = System.getProperty("user.dir") + "/bin/com/test/proxy/$Proxy0.java";
//        System.out.println(fileName);

        File file = new File(fileName);
        try {
            FileUtils.writeStringToFile(file, str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

}

3.2、完善动态代理实现

3.2.1、Proxy.java

package com.test.proxy;

import org.apache.commons.io.FileUtils;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Proxy {


    public static Object newInstance(Class interfa) throws Exception {
        String rt = "\r\n";
        String methodStr = "";
        for (Method m : interfa.getMethods()) {
            methodStr += "	@Override" + rt +
                    "	public void " + m.getName() + "() {" + rt +
                    "		long starttime = System.currentTimeMillis();" + rt +
                    "		System.out.println(\"汽车开始行驶....\");" + rt +
                    "		m." + m.getName() + "();" + rt +
                    "		long endtime = System.currentTimeMillis();" + rt +
                    "		System.out.println(\"汽车结束行驶....  汽车行驶时间:\" " + rt +
                    "				+ (endtime - starttime) + \"毫秒!\");" + rt +
                    "	}";
        }

        String str = "package com.test.proxy;\n" +
                "\n" +
                "public class $Proxy0 implements " + interfa.getName() + "{\n" +
                "\n" +
                "    private " + interfa.getName() + " m;\n" +
                "\n" +
                "    public $Proxy0(" + interfa.getName() + " m) {\n" +
                "		super();" + rt +
                "        this.m = m; \n" +
                "    }" + rt +
                methodStr + rt +
                "}";

        /**
         * 1、产生代理类的Java文件
         * System.getProperty("user.dir")  -- D:\idea_ws\java\ProxyTest1
         */
        String fileName = System.getProperty("user.dir") + "/src/com/test/proxy/$Proxy0.java";
        File file = new File(fileName);
        try {
            FileUtils.writeStringToFile(file, str);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /**
         * 2、编译源码(JDK Compiler API),产生新的类(代理类)
         */
        //编译
        //拿到编译器
        JavaCompiler complier = ToolProvider.getSystemJavaCompiler();
        //文件管理者
        StandardJavaFileManager fileMgr =
                complier.getStandardFileManager(null, null, null);
        //获取文件
        Iterable units = fileMgr.getJavaFileObjects(fileName);
        //编译任务
        JavaCompiler.CompilationTask t = complier.getTask(null, fileMgr,
                null, null, null, units);
        //进行编译
        t.call();
        fileMgr.close();

        /**
         * 3、将这个类load到内存中,产生一个新的对象(代理对象)
         */
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class c = cl.loadClass("com.test.proxy.$Proxy0");

        Constructor ctr = c.getConstructor(interfa);
        return ctr.newInstance(new Car());

    }

}

3.2.2、Client.java

package com.test.proxy;


/**
 * 测试类
 */
public class Client {

    public static void main(String[] args) throws Exception {
        Moveable moveable = (Moveable) Proxy.newInstance(Moveable.class);
        moveable.move();
    }

}

3.2.3、$Proxy0.java

package com.test.proxy;

public class $Proxy0 implements com.test.proxy.Moveable{

    private com.test.proxy.Moveable m;

    public $Proxy0(com.test.proxy.Moveable m) {
		super();
        this.m = m; 
    }
	@Override
	public void move() {
		long starttime = System.currentTimeMillis();
		System.out.println("汽车开始行驶....");
		m.move();
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶....  汽车行驶时间:" 
				+ (endtime - starttime) + "毫秒!");
	}
}

3.2.4、目录结构

3.3、动态代理实现添加InvocationHandler

3.3.1、InvocationHandler.java

package com.test.proxy;

import java.lang.reflect.Method;

public interface InvocationHandler {
	public void invoke(Object o, Method m);
}

3.3.2、TimeHandler.java
 

package com.test.proxy;

import java.lang.reflect.Method;

public class TimeHandler implements InvocationHandler {

	private Object target;
	
	public TimeHandler(Object target) {
		super();
		this.target = target;
	}

	@Override
	public void invoke(Object o, Method m) {
		try {
			long starttime = System.currentTimeMillis();
			System.out.println("汽车开始行驶....");
			m.invoke(target);
			long endtime = System.currentTimeMillis();
			System.out.println("汽车开始行驶...."
							+ (endtime - starttime) + "毫秒!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

3.3.3、Proxy.java

package com.test.proxy;

import org.apache.commons.io.FileUtils;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Proxy {


    public static Object newInstance(Class interfa, InvocationHandler handler) throws Exception {
        String rt = "\r\n";
        String methodStr = "";
        for (Method m : interfa.getMethods()) {
            methodStr += "	@Override" + rt +
                    "	public void " + m.getName() + "() {" + rt +
                    "  try{" + rt +
                    "  Method md = " + interfa.getName() + ".class.getMethod(\""
                    + m.getName() + "\");" + rt +
                    "  h.invoke(this,md);" + rt +
                    "  }catch(Exception e){ e.printStackTrace();}" + rt +
                    "	}";
        }

        String str = "package com.test.proxy;\n" + rt +
                "import java.lang.reflect.Method;" + rt +
                "import com.test.proxy.InvocationHandler;" + rt +
                "public class $Proxy0 implements " + interfa.getName() + "{\n" +
                "	public $Proxy0(InvocationHandler h) {" + rt +
                "		this.h = h;" + rt +
                "	}" + rt +
                "  private InvocationHandler h;" + rt +
                methodStr + rt +
                "}";

        /**
         * 1、产生代理类的Java文件
         * System.getProperty("user.dir")  -- D:\idea_ws\java\ProxyTest1
         */
        String fileName = System.getProperty("user.dir") + "/src/com/test/proxy/$Proxy0.java";
        File file = new File(fileName);
        try {
            FileUtils.writeStringToFile(file, str);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /**
         * 2、编译源码(JDK Compiler API),产生新的类(代理类)
         */
        //编译
        //拿到编译器
        JavaCompiler complier = ToolProvider.getSystemJavaCompiler();
        //文件管理者
        StandardJavaFileManager fileMgr =
                complier.getStandardFileManager(null, null, null);
        //获取文件
        Iterable units = fileMgr.getJavaFileObjects(fileName);
        //编译任务
        JavaCompiler.CompilationTask t = complier.getTask(null, fileMgr,
                null, null, null, units);
        //进行编译
        t.call();
        fileMgr.close();

        /**
         * 3、将这个类load到内存中,产生一个新的对象(代理对象)
         */
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class c = cl.loadClass("com.test.proxy.$Proxy0");

        Constructor ctr = c.getConstructor(InvocationHandler.class);
        return ctr.newInstance(handler);

    }

}

3.3.4、Client.java

package com.test.proxy;


/**
 * 测试类
 */
public class Client {

    public static void main(String[] args) throws Exception {
        Car car = new Car();
        InvocationHandler handler = new TimeHandler(car);
        Moveable moveable = (Moveable) Proxy.newInstance(Moveable.class, handler);
        moveable.move();
    }


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值