一、代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
二、代理对象
package com.mo.structural.proxy.pojo;
/**
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 22:39
*/
public interface Moveable {
/**
* 抽象的方法,由实现类具体实现
*/
void move();
}
package com.mo.structural.proxy.pojo;
import java.util.Random;
/**
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 22:40
*/
public class Car implements Moveable {
@Override
public void move() {
// 实现开车
try {
Thread.sleep(new Random().nextInt(2000));
System.out.println("汽车行驶中 ....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
二、静态代理
代理或被代理对象在代理之前是确定的。他们都实现了相同的接口或者继承相同的抽象类。
package com.mo.structural.proxy.steady.core;
import com.mo.structural.proxy.pojo.Car;
/**
* 方式一
* 继承实现代理
*
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 22:43
*/
public class ExtendsProxyCar extends Car {
@Override
public void move() {
long begin = System.currentTimeMillis();
System.out.println("汽车开始行使 ...");
super.move();
long end = System.currentTimeMillis() - begin;
System.out.println("汽车结束行使 ...,耗时: " + end);
}
}
package com.mo.structural.proxy.steady.core;
import com.mo.structural.proxy.pojo.Moveable;
/**
* 方式二
* 聚合实现代理
*
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 22:46
*/
public class GroupProxyCar implements Moveable {
private Moveable moveable;
public GroupProxyCar(Moveable moveable) {
this.moveable = moveable;
}
@Override
public void move() {
long begin = System.currentTimeMillis();
System.out.println("汽车开始行使 ...");
moveable.move();
long end = System.currentTimeMillis() - begin;
System.out.println("汽车结束行使 ...,耗时: " + end);
}
}
package com.mo.structural.proxy.steady.test;
import com.mo.structural.proxy.steady.core.ExtendsProxyCar;
import com.mo.structural.proxy.steady.core.GroupProxyCar;
import com.mo.structural.proxy.pojo.Car;
import org.junit.Test;
/**
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 22:49
*/
public class ProxyTest {
/**
* 继承代理测试
*/
@Test
public void extendsTest() {
ExtendsProxyCar extendsProxyCar = new ExtendsProxyCar();
extendsProxyCar.move();
}
/**
* 聚合代理测试
*/
@Test
public void groupTest() {
Car car = new Car();
GroupProxyCar groupProxyCar = new GroupProxyCar(car);
groupProxyCar.move();
}
/**
* 说明:
* 聚合代理相比继承代理更加灵活,能够将代理进行不同组合,实现不同的功能
*/
}
三、动态代理
jdk代理
package com.mo.structural.proxy.dynamic.jdk;
import com.mo.structural.proxy.pojo.Car;
import com.mo.structural.proxy.pojo.Moveable;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 方式一
* jdk代理的步骤
* 1. 实现InvocationHandler接口及具体业务
* 2. 创建被代理的类以及接口
* 3. 调用Proxy的静态方法,创建一个代理类
* 4. 代理调用方法
* <p>
* jdk代理的说明
* 只能代理实现接口的类
*
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 23:14
*/
public class TimeHandler implements InvocationHandler {
private Object object;
public TimeHandler(Object object) {
this.object = object;
}
/**
* @param proxy 被代理的对象
* @param method 被代理对象的方法
* @param args 方法的参数
* @return 方法的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long begin = System.currentTimeMillis();
System.out.println("汽车开始行使 ...");
method.invoke(object, args);
long end = System.currentTimeMillis() - begin;
System.out.println("汽车结束行使 ...,耗时: " + end);
return null;
}
@Test
public void jdk() {
Car car = new Car();
Class<? extends Car> aClass = car.getClass();
InvocationHandler handler = new TimeHandler(car);
/**
* ClassLoader loader 类加载器
* Class<?>[] interfaces 实现的接口
* InvocationHandler h
*/
Moveable moveable = (Moveable) Proxy.newProxyInstance(aClass.getClassLoader(), aClass.getInterfaces(), handler);
moveable.move();
}
}
cglib代理
package com.mo.structural.proxy.dynamic.cglib;
/**
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 23:28
*/
public class People {
public void move(){
System.out.println("人在前进中 ...");
}
}
package com.mo.structural.proxy.dynamic.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;
import java.lang.reflect.Method;
/**
* cglib实现代理说明
* 是通过继承的方式实现代理的,所以被final修改的类是不能被代理的
* <p>
* 依赖
* <dependency>
* <groupId>cglib</groupId>
* <artifactId>cglib</artifactId>
* <version>3.2.5</version>
* </dependency>
*
* @author x.pan
* @email px5215201314@163.com
* @date 2020/7/12 23:29
*/
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 args 目标方法的反射参数
* @param methodProxy 代理类的实例
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
long begin = System.currentTimeMillis();
System.out.println("开始行使 ...");
// 代理调用父类的方法
methodProxy.invokeSuper(o, args);
long end = System.currentTimeMillis() - begin;
System.out.println("结束行使 ...,耗时: " + end);
return null;
}
@Test
public void cglib() {
CglibProxy cglibProxy = new CglibProxy();
People proxy = (People) cglibProxy.getProxy(People.class);
proxy.move();
}
}