定义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
分类
- 静态代理
静态代理就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
//抽象对象
public interface UserService {
public void getByUserId();
}
//真实对象
public class UserServiceImpl implements UserService {
public void getByUserId() {
System.out.println("查询方法省略……");
}
}
//代理对象
public class UserServiceProxy implements UserService {
private UserService userService;
public UserServiceProxy(UserService userService) {
this.userService = userService;
}
public void getByUserId() {
System.out.println("方法执行前");
userService.getByUserId();
System.out.println("方法执行后");
}
}
//测试类
public class StaticProxtTest {
public static void main(String[] args) {
UserService userServiceProxy = new UserServiceProxy(new UserServiceImpl());
userServiceProxy.getByUserId();
}
}
方法执行前
查询方法省略……
方法执行后
- 动态代理
动态代理类的源码是程序在运行期间由JVM根据反射等机制动态生成的,所以不存在代理类的字节码文件。代理角色和真实角色的联系在程序运行时确定。
//抽象对象和真实对象同上
//代理对象
public class UserServiceDynamicProxy implements InvocationHandler {
private UserService userService;
public UserServiceDynamicProxy(UserService userService) {
this.userService = userService;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前");
Object object = method.invoke(userService, args);
System.out.println("方法执行后");
return object;
}
}
//测试类
public class DynamicProxyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserServiceDynamicProxy dynamicProxy = new UserServiceDynamicProxy(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{UserService.class}, dynamicProxy);
proxy.getByUserId();
}
}
方法执行前
查询方法省略……
方法执行后
优点:
业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。
能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
缺点:
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。
实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂,例如远程代理。