代理:将某对象的方法交给代理对象处理,并且可以扩展,即可以在方法调用前后添加其他代码。之后要调用该方法时不通过原对象调用,而是用代理对象去调用
1.若对象(User)的某方法(hello)需要被代理,则该对象需要继承一个接口(UserImpl,自己定义),并在该接口中声明该方法(hello)
2.创建一个InvocationHandler接口的实现类ProxyHandler,将被代理的方法交给ProxyHandler完成(通过直接调用,但可以在方法调用前后添加其他代码,从而扩展原来方法的功能)
3.通过 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); 创建代理对象。生成 实现某接口(interfaces)、代理了原对象(User)声明在该接口中方法的、并且代理后的方法的实现为h.invoke()的 代理对象
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface UserImpl {
public void hello();
}
class User implements UserImpl {
@Override
public void hello() {
System.out.println("User");
}
}
class ProxyHandler<T> implements InvocationHandler {
// 被代理的对象
private T target;
public ProxyHandler(T target) {
this.target = target;
}
//代理后的方法的实现,即调用代理对象的方法(userProxy.hello())相当于调用该invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Proxy Start");
//调用被代理对象的方法(原对象的方法)
Object r = method.invoke(target, args);
//不能用Object r = method.invoke(proxy, args); 会死循环,因为proxy是代理对象(userProxy),会再次调用userProxy.hello()
System.out.println("Proxy End");
return r;
}
}
public class Test {
public static void main(String[] args) {
User user = new User();
UserImpl userProxy = (UserImpl) Proxy.newProxyInstance(user.getClass().getClassLoader(),
new Class<?>[] { UserImpl.class }, new ProxyHandler<User>(user));
userProxy.hello();
}
}