Java 代理模式 Proxy

简述:提供了对目标对象的间接访问方式,即通过代理访问目标对象.

目的:为其他对象提供一个代理以控制对某个对象的访问。

作用:
1.通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,
  同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。(解耦)
2.可以实现拦截方法,修改原方法的参数和返回值,满足了代理自身需求和目的,也就是是代理的方法增强性。(高扩展性)

代理类:负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

图解:
Java 代理模式 Proxy
静态代理:

–公共接口(抽象角色)

public interface Subject {
	void vist();
}

–实际对象 (被代理对象)

public class RealSubject implements Subject{
	private String name = "我是真实对象";
	public void vist() {
		System.out.println(name);
	}
}

–代理对象

public class ProxySubject implements Subject{
	
	private Subject subject;//接口
	
	public ProxySubject(Subject subject) {
	        this.subject = subject;       //这里初始化了,发现木有!相当于传入的 被代理对象,
	        							  //实现的是 被代理对象的方法,因为 实际对象也实现了公共接口!
	    }
	
	public void vist() {
		System.out.println("我是一号代理----");
		subject.vist();
	}

}

–客户端 测试

public class Client {
	
	public static void main(String[] args) {
		ProxySubject p = new ProxySubject(new RealSubject()); //看这,构造方法里面放的是 真实对象!
	    p.vist();							 //然而这个p 确是 代理对象实例,由代理对象执行的 .vist() 方法!
	}

}

控制台输出:
Java 代理模式 Proxy

动态代理:

公共接口,实际对象,不变! 只是代理类变了.
由于运用的反射,所有在运行实,才知道被代理的对象.

–代理类:

public class DynamicProxy  implements InvocationHandler{
									//(JDK)java.lang.reflect.InvocationHandler:这是调用处理器接口,
									//它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,
									//通常在该方法中实现对委托类的代理访问。
	private Object object;
	
	public DynamicProxy(Object object){
		this.object=object;
	}

	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
			
		Object result =method.invoke(object, args); //前面说的反射中的,方法调用. invoke(对象,方法参数)
		return result;
		
	}

}

–客户端 测试

public class ProxyClient {
	
	
	public static void main(String[] args) {
		Subject relSubject = new RealSubject();
		DynamicProxy proxy = new DynamicProxy(relSubject);//放入真实对象
		ClassLoader classLoader = relSubject.getClass().getClassLoader();//获取真实对象的类加载器
		Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new  Class[]{Subject.class}, proxy);
		subject.vist();
	}
	
}

静态代理,问题解析:

  1. 增加了代码维护的复杂度。

Java 代理模式 Proxy
2.代理的对象过多,代理的方法不同就会出现毛病!
就像这样:
Java 代理模式 Proxy

图片来自大佬:https://blog.csdn.net/WangQYoho/article/details/77584832

3.在编译器就已经确定被代理的对象


动态代理,问题解析:

–优点

  1. 在运行时,通过反射机制实现动态代理,并且能够代理各种类型的对象。
  2. 实现无侵入式的代码扩展。