设计模式之代理模式
代理模式
- 代理模式分为静态代理和动态代理.下图为静态代理结构图:
-
静态代理示例代码:
// 抽象主题接口 public interface Subject { void request(); } // 具体主题角色 public class RealSubject implements Subject{ @Override public void request() { System.out.println("真实对象处理请求..."); Random random = new Random(); try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } // 代理角色 public class Proxy implements Subject{ private Subject subject; public Proxy(Subject subject) { this.subject = subject; } @Override public void request() { System.out.println("代理对象开始处理请求..."); before(); subject.request(); after(); } private void after() { System.out.println("proxy end..."); } private void before() { System.out.println("proxy start..."); } } // 测试 public class ProxyTest { public static void main(String[] args) { Proxy proxy = new Proxy(new RealSubject()); proxy.request(); } }
-
JDK动态代理示例代码:
// 抽象接口 public interface Person { void findWork(); } // 具体对象 public class Worker implements Person{ @Override public void findWork() { System.out.println("打工人要找工作..."); } } // 代理类,实现的是InvocationHandler接口 public class JdkHr implements InvocationHandler { private Person target; public Person getInstance(Person person){ this.target = person; Class<? extends Person> targetClass = target.getClass(); return (Person) Proxy.newProxyInstance(targetClass.getClassLoader(), targetClass.getInterfaces(), this); } @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { before(); Object invoke = method.invoke(this.target, objects); after(); return invoke; } private void after() { System.out.println("proxy end..."); } private void before() { System.out.println("proxy start..."); } } // 测试 public class JdkProxyTest { public static void main(String[] args) { // 这一行设置保存程序运行时的动态代理类class文件,方便查看 System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true"); JdkHr hr = new JdkHr(); Person person = hr.getInstance(new Worker()); person.findWork(); } }
-
CGLib动态代理示例代码:
```java // 抽象接口 public interface Person { void findWork(); } // 具体对象 public class Worker implements Person{ @Override public void findWork() { System.out.println("打工人要找工作..."); } } // 代理类,实现的是MethodInterceptor接口 public class CglibHr implements MethodInterceptor { public Object getInstance(Class<?> clazz){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object obj = methodProxy.invokeSuper(o, objects); after(); return obj; } private void after() { System.out.println("proxy end..."); } private void before() { System.out.println("proxy start..."); } } // 测试 public class CglibProxyTest { public static void main(String[] args) { // 这一行设置保存程序运行时的动态代理类class文件 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "cglibProxy/"); CglibHr hr = new CglibHr(); Person person = (Person) hr.getInstance(Worker.class); person.findWork(); } } ```
-
JDK和CGLib动态代理对比:
- 静态代理和动态代理对比:
-
总结:
代理模式优点:将代理对象与真实被调用目标对象分离,降低了系统耦合性,扩展性好,并且可以增强目标对象的功能;
代理模式缺点:系统中类的数量增加,导致处理请求的速度变慢,增加了系统的复杂度.