代理模式

本文深入解析Java动态代理及代理模式的核心概念,通过具体代码示例展示如何使用Java的动态代理创建代理对象,以及如何在实际开发中灵活运用代理模式解决需求问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代理模式一般涉及到的角色有

1、抽象角色:声明真实对象和代理对象的共同接口

2、代理角色:代理对象角色内部含有对真实对象的引用,从而可以操纵真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象:同时代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装

3、真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

写道
package com.test.proxy;
/**
*  抽象角色:声明真实对象和代理对象的共同接口
* @author Administrator
*
*/
public abstract class Subject {

public abstract void request();

}

 

package com.test.proxy;
/**
 * 真实角色
 * @author Administrator
 *
 */
public class RealObject extends Subject {

	@Override
	public void request() {
		System.out.println("from real subject");

	}

}
package com.test.proxy;
/**
 * 代理角色
 * @author Administrator
 *
 */
public class ProxySubject extends Subject {

	
	private RealObject  realSubject;
	
	
	
	@Override
	public void request() {
		this.preRequest();
		if(null == realSubject)
		{
			realSubject = new RealObject();
		}
		realSubject.request();
		this.afterRequest();
	}

	private void preRequest()
	{
		System.out.println("pre request");
		
	}
	
	private void afterRequest()
	{
		System.out.println("after request");
		
	}
}
写道
package com.test.proxy;
/**
*  客户端
* @author Administrator
*
*/
public class Client {

public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();

}
}
由上述代码可以看出,客户实际调用的是RealSubject累的request方法,现在用 ProxySubject来代理realsubject同样达到了目的,同时还封装了其它的方法(preReuqest 、afterRequest)可以处理一些其他的问题
另外如果按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致累的急剧膨胀:此外如果事先不知道真实角色,该如何使用代理呢?这个问题可以使用Java的动态代理解决。
java 的动态代理位于java.lang.reflect包下,一般主要涉及到一下两个类:
1、interface InvocationHandler 该接口仅定义了一个方法
     public object invoke(Object object,Method method,Object[] args);
    在实际应用时,第一个参数object一般是指代理类,method是被代理的方法,如上例中的request(),args为该法方法的参数数组。这个抽象方法在代理类中动态实现。
2、 Proxy:该类即为动态代理类,作用类似于上面的ProxyObject(代理角色),其主要包含以下内容:
    protected Proxy(InvocationHandler h):构造函数用于给内部的h赋值。
   static Class getProxyClass(ClassLoader classLoader,Class[] interfaces):获得一个代理类,其中classloader是类装载器,interfaces是真实类拥有的所有接口的数组。
    static Object newProxyInstance(ClassLoader classLoader,Class[] interfaces,InvocationHandler h)
返回代理类的实例,返回后的代理类可以当做被代理类来使用。
package com.test.dynamicproxy;

public interface Subject {

	void request();
}
 
 
package com.test.dynamicproxy;

public class RealSubject implements Subject {

	@Override
	public void request() {
		System.out.println("fron real subject");
	}
	
	
}
 
 
package com.test.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyObject implements InvocationHandler {

	private Object object;
	
	public ProxyObject(Object object) {
		this.object = object;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("pre request");
		method.invoke(object, args);
		System.out.println("after request");
		return null;
	}
	
}
 
package com.test.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;


public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		RealSubject subject = new RealSubject();
		
		InvocationHandler in = new  ProxyObject(subject);
		
		Class<?> clazz = subject.getClass();
		
		Subject object = (Subject)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), in);
		
		object.request();
	}

}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值