代理模式的应用场景
代理模式分为静态代理和动态代理。静态代理的代理对象,在程序编译时已经写好 Java 文件了,直接 new 一个代理对象即可。动态代理产生代理对象的时机是运行时动态生成,它没有 Java 源文件,直接生成字节码文件实例化代理对象。
静态代理的实现有两种:通过接口和通过继承。
静态代理 - 通过接口方式
类图
代码实现
UserService
public interface UserService {
public Boolean login(String username, String password);
}
复制代码
UserServiceImpl
public class UserServiceImpl implements UserService {
@Override public Boolean login(String username, String password) { return "admin".equals(username) && "admin".equals(password); }
}
复制代码
UserServiceProxy
public class UserServiceProxy implements UserService {
private final UserService userService;
public UserServiceProxy(UserService userService) { this.userService = userService; }
@Override public Boolean login(String username, String password) { long t1 = System.nanoTime(); System.out.println("start login"); Boolean result = userService.login(username, password); System.out.println("end login"); long t2 = System.nanoTime(); System.out.println("time: " + (t2 - t1) + "ns"); return result; }
}
复制代码
Main
public class Main {
public static void main(String[] args) { UserService userService = new UserServiceProxy(new UserServiceImpl()); Boolean result = userService.login("admin", "admin"); System.out.println("result: " + result); }
}
复制代码
静态代理 - 通过继承方式
类图
代码实现
UserService
public interface UserService {
public Boolean login(String username, String password);
}
复制代码
UserServiceImpl
public class UserServiceImpl implements UserService {
@Override public Boolean login(String username, String password) { return "admin".equals(username) && "admin".equals(password); }
}
复制代码
UserServiceProxy
public class UserServiceProxy extends UserServiceImpl {
@Override public Boolean login(String username, String password) { long t1 = System.nanoTime(); System.out.println("start login"); Boolean result = super.login(username, password); System.out.println("end login"); long t2 = System.nanoTime(); System.out.println("time: " + (t2 - t1) + "ns"); return result; }
}
复制代码
Main
public class Main {
public static void main(String[] args) { UserService userService = new UserServiceProxy(); Boolean result = userService.login("admin", "admin"); System.out.println("result: " + result); }
}
复制代码
动态代理
上面的代码实现有两个问题:
我们需要在代理类中,将原始类中的所有的方法,都重新实现一遍,并且为每个方法都附加相似的代码逻辑。
如果要添加的附加功能的类有不止一个,我们需要针对每个类都创建一个代理类。
这时我们就需要用到动态代理(Dynamic Proxy),就是我们不事先为每个原始类编写代理类,而是在运行的时候,动态地创建原始类对应的代理类,然后在系统中用代理类替换掉原始类。
如何实现动态代理呢?
Java 语言本身就已经提供了动态代理的语法(实际上,动态代理底层依赖的就是 Java 的反射语法)。
类图
UserService
public interface UserService {
public Boolean login(String username, String password);
}
复制代码
UserServiceImpl
public class UserServiceImpl implements UserService {
@Override public Boolean login(String username, String password) { return "admin".equals(username) && "admin".equals(password); }
}
复制代码
DynamicProxyHandler
public class DynamicProxyHandler implements InvocationHandler {
private Object target;
public DynamicProxyHandler(Object target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long t1 = System.nanoTime(); System.out.println("start " + target.getClass().getName() + ":" + method.getName()); Object result = method.invoke(target, args); System.out.println("end " + target.getClass().getName() + ":" + method.getName()); long t2 = System.nanoTime(); System.out.println("time: " + (t2 - t1) + "ns"); return result; }
}
复制代码
DynamicProxy
public class DynamicProxy {
public Object createProxy(Object target) { ClassLoader classLoader = target.getClass().getClassLoader(); Class<?>[] interfaces = target.getClass().getInterfaces(); DynamicProxyHandler handler = new DynamicProxyHandler(target); return Proxy.newProxyInstance(classLoader, interfaces, handler); }
}
复制代码
Main
public class Main {
public static void main(String[] args) { DynamicProxy proxy = new DynamicProxy(); UserService userService = (UserService) proxy.createProxy(new UserServiceImpl()); Boolean result = userService.login("admin", "admin"); System.out.println("result: " + result); }
}
复制代码
评论