JDK的代理模式

jdk的代理模式

1.代理模式的定义:

为其他对象提供一种代理一控制对这个对象的访问,代理对对象起到中介作用,用于去掉部分功能服务或者是增加一些额外的服务

2.静态代理:

代理和被代理之间的关系是确定的,他们都是实现相同的接口或者是继承相同的抽象类;

 

创建接口

public interface Moveable {

void move();

}

创建车实现Moveable方法

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_以继承的方式实现静态代理:

public class Car2 extends Car {

@Override

public void move() {

long starttime = System.currentTimeMillis();

System.out.println("汽车开始行驶....");

super.move();

long endtime = System.currentTimeMillis();

System.out.println("汽车结束行驶.... 汽车行驶时间:"

+ (endtime - starttime) + "毫秒!");

}

}

② 聚合的方式:

创建Car3__以聚合的方式实现静态代理:

public class Car3 implements Moveable {

public Car3(Car car) {

super();

this.car = car;

}

private Car car;

@Override

public void move() {

long starttime = System.currentTimeMillis();

System.out.println("汽车开始行驶....");

car.move();

long endtime = System.currentTimeMillis();

System.out.println("汽车结束行驶.... 汽车行驶时间:"

+ (endtime - starttime) + "毫秒!");

}

}

两者之间都可以实现静态代理,但是相比之下,使用聚合的方式更好:

比如: 上面的例子只是增加了时间记录那么需要创建一个Car2,那么如果在增加一个记录行驶日志呢?那么就要再创建一个Car4,再增加一个权限呢?那么就需要再创建一个Car5来继承Car4,.........这样的话没增加一个功能就需要创建一个实例.但是使用聚合的方式就不会这样了

同样创建一个move接口:

public interface Moveable {

void move();

}

再创建一个实例Car实现Moveable接口

public class Car implements Moveable {

@Override

public void move() {

//实现开车

try {

Thread.sleep(new Random().nextInt(1000));

System.out.println("汽车行驶中....");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

创建时间代理_用于记录时间

public class CarTimeProxy implements Moveable {

public CarTimeProxy(Moveable m) {

super();

this.m = m;

}

private Moveable m;

@Override

public void move() {

long starttime = System.currentTimeMillis();

System.out.println("汽车开始行驶....");

m.move();

long endtime = System.currentTimeMillis();

System.out.println("汽车结束行驶.... 汽车行驶时间:"

+ (endtime - starttime) + "毫秒!");

}

}

创建日志代理_用于记录日志

public class CarLogProxy implements Moveable {

public CarLogProxy(Moveable m) {

super();

this.m = m;

}

private Moveable m;

@Override

public void move() {

System.out.println("日志开始....");

m.move();

System.out.println("日志结束....");

}

}

创建测试类

public static void main(String[] args) {

Car car = new Car();

CarLogProxy clp = new CarLogProxy(car);

CarTimeProxy ctp = new CarTimeProxy(clp);

clp.move();//此时是先执行日志,再执行记录行驶时间

ctp.move();//此时是先执行记录行驶时间,再执行记录日志

}

这样可以看出聚合相比于继承要灵活了很多

但是,像权限,日志,时间这种公共的代理,后面如果再创建了一个其他对象,如飞机,火车,自行车呢?那是不是就要创建不同的实例呢?然后这种情况下就需要用到动态代理了

3.动态代理

动态代理的原理图如下所示:

Java动态代理类位于java.lang.reflect包下,一般主要涉及到一下两个类:

(1) Interface InvocationHandler :

该接口中仅定义了一个方法:public object invoke (Object obj,Method method, Object[] args)在实际使用的时候,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组,这个抽象方法在代理类中被动态实现;

(2)Proxy :

该类即为动态代理类

static Object newProxyInstance(ClassLoader loader,Class[] interf aces,

InvocationHandler h): 返回代理类的一个实例,返回后的代理类可以当作被

代理类使用(可使用被代理类的在接口中声明过的方法)

示例:

创建时间处理的handler

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class TimeHandler implements InvocationHandler {

public TimeHandler(Object target) {

super();

this.target = target;

}

private Object target;

/*

* 参数:

* proxy 被代理对象

* method 被代理对象的方法

* args 方法的参数

* 返回值:

* Object 方法的返回值

* */

@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();

System.out.println("汽车结束行驶.... 汽车行驶时间:"

+ (endtime - starttime) + "毫秒!");

return null;

}

}

JDK动态代理测试:

/**

* JDK动态代理测试类

*/

public static void main(String[] args) {

Car car = new Car();

InvocationHandler h = new TimeHandler(car);

Clas s<?> cls = car.getClass();

/**

* loader 类加载器

* interfaces 实现接口

* h InvocationHandler

*/

Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),

cls.getInterfaces(), h);

m.move();

}

总结:

动态代理实现步骤

1.创建一个实现接口InvocationHandler的类,它

必须实现i nvoke方法

2.创建被代理的类以及接口

3.调用Proxy的静态方法,创建一个代理类

newProxyInstance(ClassLoader loader,Class[]

interfaces,InvocationHandler h)

4.通过代理调用方法

动态代理实现思路

实现功能: 通过Proxy的newProxyInstance返回代理对象

1、声明一段源码(动态产生代理)

2、编译源码(JDK Compiler API),产生新的类(代理类)

3、将这个类load到内存当中,产生一个新的对象(代理对象)

4、return 代理对象

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值