在编程中,Java代理是一种广泛使用的设计模式,可以用于实现各种功能,如安全检查、修改原始对象的行为、跟踪等。Java提供了两种代理模式:静态代理和动态代理。静态代理需要在编译期提前知道代理类和委托类,而动态代理则在运行时动态生成代理类并进行代理。
一、STATIC PROXY(静态代理)
静态代理是最基本的代理模式。在这种模式中,代理类和被代理类都必须实现同一个接口。
- 创建一个接口并定义方法:
public interface Subject {
void request();
}
- 创建一个实现Subject接口的RealSubject类:
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("Request from RealSubject");
}
}
- 创建一个实现Subject接口的Proxy类,并将RealSubject实例作为一个字段:
public class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("Request from Proxy");
realSubject.request();
}
}
- 在主类中创建RealSubject和Proxy实例,并调用request方法:
public class Main {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.request();
}
}
二、DYNAMIC PROXY(动态代理)
动态代理是在运行时动态生成代理类,并进行代理。Java的动态代理机制只能代理接口,不能代理类。
- 创建一个接口并定义方法:
public interface Subject {
void request();
}
- 创建一个实现Subject接口的RealSubject类:
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("Request from RealSubject");
}
}
- 创建一个实现InvocationHandler接口的DynamicProxyHandler类,并将RealSubject实例作为一个字段:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyHandler implements InvocationHandler {
private Object realSubject;
public DynamicProxyHandler(Object realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Request from DynamicProxyHandler");
return method.invoke(realSubject, args);
}
}
- 在主类中创建RealSubject实例和Proxy实例,并调用request方法:
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject proxy = (Subject) Proxy.newProxyInstance(
RealSubject.class.getClassLoader(),
RealSubject.class.getInterfaces(),
new DynamicProxyHandler(realSubject)
);
proxy.request();
}
}
在使用Java代理设置时,需要注意的是,代理类必须在运行时才能确定,因此需要使用Java的反射API。此外,代理类和委托类必须实现相同的接口,否则无法进行代理。
相关问答FAQs:
1. 如何在Java中设置代理服务器?
- 问题描述: 我想在Java程序中设置代理服务器,以便在访问外部资源时使用代理。如何在Java中实现这一功能?
- 回答: 在Java中设置代理服务器可以使用
System.setProperty()
方法,设置http.proxyHost
和http.proxyPort
属性来指定代理服务器的主机名和端口号。例如,您可以使用以下代码设置代理服务器:
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
确保将"proxy.example.com"和"8080"替换为您实际使用的代理服务器的主机名和端口号。
2. 如何在Java中设置代理服务器的认证信息?
- 问题描述: 我的代理服务器要求进行身份验证。在Java中,我应该如何设置代理服务器的认证信息?
- 回答: 如果您的代理服务器需要身份验证,您可以使用
java.net.Authenticator
类来设置代理服务器的认证信息。首先,创建一个继承自Authenticator
类的子类,并重写protected PasswordAuthentication getPasswordAuthentication()
方法以返回包含代理服务器的用户名和密码的PasswordAuthentication
对象。然后,使用Authenticator.setDefault()
方法将您的子类实例设置为默认的Authenticator
。以下是一个示例代码:
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
请将"username"和"password"替换为您实际使用的代理服务器的用户名和密码。
3. 如何在Java中设置代理服务器的超时时间?
- 问题描述: 我希望能够在Java程序中设置代理服务器的超时时间,以避免长时间等待代理服务器响应。有什么方法可以实现这个功能?
- 回答: 在Java中设置代理服务器的超时时间可以使用
java.net.Proxy
类和java.net.URLConnection
类。首先,创建一个Proxy
对象,并使用Proxy
的构造函数指定代理服务器的主机名和端口号。然后,使用openConnection(Proxy proxy)
方法打开一个URLConnection
对象,并设置连接的超时时间。以下是一个示例代码:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080));
URLConnection connection = new URL("http://example.com").openConnection(proxy);
connection.setConnectTimeout(5000); // 设置连接超时时间为5秒
connection.setReadTimeout(5000); // 设置读取超时时间为5秒
请将"proxy.example.com"和"8080"替换为您实际使用的代理服务器的主机名和端口号,以及将"http://example.com"替换为您要访问的外部资源的URL。
原创文章,作者:Edit2,如若转载,请注明出处:https://docs.pingcode.com/baike/384357