代理模式
常见的代理模式
- 远程代理
- 虚拟代理
- 保护代理
- 智能引用代理
代理模式实现 —— 静态代理
代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。
// 定义一个接口
public interface Moveable {
public void move();
}
public class Car implements Moveable {
@Override
public void move() {
System.out.println("汽车行驶!");
}
}
继承实现静态代理
// 使用继承实现静态代理
public class Car1 extends Car {
@Override
public void move() {
System.out.println("开始...");
super.move();
System.out.println("结束...");
}
}
// 测试
public class Main {
public static void main(String[] args) {
Moveable moveable = new Car1();
moveable.move();
}
}
使用聚合实现静态代理(更好这个,可以更好地实现代理的叠加)
public class Car2 implements Moveable {
private Car car;
public Car2(Car car) {
this.car = car;
}
@Override
public void move() {
System.out.println("开始...");
car.move();
System.out.println("结束...");
}
}
// 测试
public class Main {
public static void main(String[] args) {
Moveable moveable1 = new Car2(new Car());
moveable1.move();
}
}
代理模式实现 —— 动态代理
1、JDK动态代理
只能代理实现接口的类;没有实现接口不能实现JDK的动态代理
// 代理接口
public interface Moveable {
public void move();
}
// 代理类
public class Car implements Moveable {
@Override
public void move() {
System.out.println("汽车行驶!");
}
}
// 动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyProxy<T> implements InvocationHandler {
private T obj;
public MyProxy(T obj) {
this.obj = obj;
}
/**
* @param proxy 代表动态代理对象
* @param method 代表正在执行的方法
* @param args 代表调用目标方法传入得实参
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" + method.getName() + "方法");
Object result = method.invoke(obj, args);
return result;
}
}
// 动态代理测试类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Main1 {
public static void main(String[] args) {
Moveable car = new Car();
InvocationHandler handler = new MyProxy<Moveable>(car);
Moveable moveable = (Moveable) Proxy.newProxyInstance(Moveable.class.getClassLoader(), new Class<?>[] {Moveable.class} , handler);
moveable.move();
}
}
2、cglib动态代理
针对类来实现代理的;对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用。
需要引入 cglib-3.1.jar和asm-5.2.jar的版本,注意cglib和asm需要对应,否则会报错。
// 代理的类
public class MyCar {
public void move() {
System.out.println("移动");
}
}
// cglib动态代理
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 ProxyCglib implements MethodInterceptor {
private Object object;
public Object getProxy(Object object) {
this.object = object;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.object.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
/**
*
* @param obj 目标类的实例
* @param method 目标方法的反射对象
* @param args 方法的参数
* @param methodProxy 代理类的实例
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开始...");
methodProxy.invokeSuper(obj, args);
System.out.println("结束...");
return null;
}
}
// 代理测试类
public class Main2 {
public static void main(String[] args) {
ProxyCglib cglib = new ProxyCglib();
MyCar car = (MyCar)cglib.getProxy(new MyCar());
car.move();
}
}