给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。
静态代理
package proxy;
public interface Subject {
void doSomthing();
}
package proxy;
public class RealSubject implements Subject{
@Override
public void doSomthing() {
System.out.println("I need do some things");
}
}
package proxy;
public class ProxySubject implements Subject {
private Subject subject;
@Override
public void doSomthing() {
subject = new RealSubject();
subject.doSomthing();
}
}
动态代理
动态代理相关API
API | 用途 |
---|---|
Proxy#newProxyInstance |
创建一个代理 |
InvocationHandler#invoke |
用于处理动态代理类对对象的方法调用 |
如何创建动态代理
第一步,实现InvocationHandler接口,并重写invoke方法。在invoke方法中处理代理类中需要处理的逻辑。
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyHandler implements InvocationHandler {
Object proxied;
public DynamicProxyHandler(Object proxied){
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method="+method+" proxy="+proxy.getClass());
if (args != null) {
for (Object arg: args) {
System.out.println("arg="+arg);
}
}
return method.invoke(proxied, args);
}
}
第二步,使用Proxy#newProxyInstance创建代理对象。newProxyInstance方法的参数分别为:
- ClassLoader loader:指定当前目标对象使用类加载器,用null表示默认类加载器
- Class [] interfaces:需要实现的接口数组
- InvocationHandler handler:调用处理器,执行目标对象的方法时,会触发调用处理器的方法,从而把当前执行目标对象的方法作为参数传入
package proxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
// 动态代理
Subject real = new RealSubject();
Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
new Class[]{Subject.class}, new DynamicProxyHandler(real));
proxy.doSomthing();
}
}
动态代理特点
- 不需要手动创建代理类,它会在运行期,通过反射机制创建一个实现了一组给定接口的新类
- 必须要实现InvocationHandler接口
- 接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。