代理模式是结构模式中的一种,代理模式就是给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理.
代理模式分为以下三个角色:
抽象主题(Subject):代理元与代理对象共同具有的接口
真实主题(realProxy):代理元
代理主题(Proxy):代理对象,包含了对真实主题的引用
代理模式是UML:
代理模式分为静态代理和动态代理:
静态代理:
package com.qingdao.proxy;
public interface UserInterface {
public void addUser();
}
package com.qingdao.proxy;
public class UserImpl implements UserInterface{
@Override
public void addUser() {
System.out.println("in UserImpl -->Success-->addUser()");
}
}
package com.qingdao.proxy;
public class UserProxy implements UserInterface {
private UserInterface userInterface;
public UserProxy(UserInterface userInterface) {
this.userInterface = userInterface;
}
@Override
public void addUser() {
System.out.println("in UserProxy start-->addUser()");
userInterface.addUser();
System.out.println("in UserProxy end-->addUser()");
}
}
package com.qingdao.proxy;
public class Client {
public static void main(String[] args) {
new UserProxy(new UserImpl()).addUser();
}
}
动态代理:
由于静态代理会产生大量的类,因此JDK提供了动态代理的功能,通过InvocationHandler接口和Proxy类实现动态代理的功能
package com.qingdao.proxy;
public class UserImpl implements UserInterface{
@Override
public void addUser(String username, String password) {
System.out.println("in UserImpl-->addUser(name,password) "+username+"--->"+password);
}
}
package com.qingdao.proxy;
public interface UserInterface {
void addUser(String username,String password);
}
package com.qingdao.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserProxy implements InvocationHandler {
private Object target;//代理元
public Object newProxyInstance(Object target){
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("参数列表--->");
for(Object arg : args){
System.out.println(arg);
}
System.out.println("调用开始-->>" + method.getName()+"--成功");
method.invoke(target, args);
System.out.println("调用结束-->>" + method.getName()+"--成功");
return null;
}
}
package com.qingdao.proxy;
public class Client {
public static void main(String[] args) {
UserProxy publicProxy = new UserProxy();
UserInterface userImpl = (UserInterface) publicProxy
.newProxyInstance(new UserImpl());
userImpl.addUser("王五", "17");
}
}
执行结果:
参数列表--->
王五
17
调用开始-->>addUser--成功
in UserImpl-->addUser(name,password)王五--->17
调用结束-->>addUser--成功