一.代理模式
代理模式分为两种
- 静态代理
- 动态代理
二.静态代理
静态代理是代理模式种最简单的一种,如果想要理解代理模式,千万要好好的理解静态代理。
举一个栗子
假如你要去租房的话,那你会去找谁,房东?中介?一般来讲,我们是不是会去找中介而不是房东。
这个租房的这个例子种,我是实际的类(被代理类),而中介是代理类
在静态代理中,被代理类和代理类都要实现同样的接口。
以下是简单例子代码
接口
public interface Rent { void rent(); }
实际的类(被代理类)
public class Person implements Rent { @Override public void rent() { System.out.println("老子要租房子!"); } }
代理类
1 public class Proxy implements Rent{ 2 private Person person; 3 4 public Proxy() { 5 } 6 7 public Proxy(Person person) { 8 this.person = person; 9 } 10 11 @Override 12 public void rent() { 13 pay(); 14 person.rent(); 15 } 16 17 }
测试结果
1 public class ProxyTest { 2 public static void main(String[] args) { 3 Person person = new Person(); 4 Proxy proxy = new Proxy(person); 5 proxy.rent(); 6 } 7 }
以上的就是最简单的静态代理代码。需要注意的有以下几点
- 代理类和被代理类都必须实现接口
- 代理类需要将被代理类作为内部类,然后在调用被代理类的方法
稍微进阶的栗子,可以在代理类中添加操作而不改变被代理类。
代理类
1 public class Proxy implements Rent{ 2 private Person person; 3 4 public Proxy() { 5 } 6 7 public Proxy(Person person) { 8 this.person = person; 9 } 10 11 @Override 12 public void rent() { 13 pay(); 14 person.rent(); 15 } 16 public void pay(){ 17 System.out.println("老子收了一亿的房租,就不给你"); 18 } 19 }
三.动态代理
动态代理是代理模式而中的难点也是重点,相较静态代理,动态代理有不小的优势,比如
- 对于静态代理来说,一个类就需要写一个静态代理,比较繁琐
- 静态代理的代理是写死的
以下是动态代理的简单栗子
接口
1 public interface Rent { 2 void rent(); 3 }
被委托类
1 public class Person implements Rent { 2 @Override 3 public void rent() { 4 System.out.println("你大爷的"); 5 } 6 }
委托工具类
1 public class ProxyInvocationHandler implements InvocationHandler { 2 private Object target; 3 4 public void setTarget(Object target) { 5 this.target = target; 6 } 7 8 9 public Object getProxy(){ 10 return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); 11 } 12 @Override 13 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 14 Object result = method.invoke(target, args); 15 return result; 16 } 17 }
测试类
1 public class ProxyTest { 2 public static void main(String[] args) { 3 Person person = new Person(); 4 ProxyInvocationHandler pih = new ProxyInvocationHandler(); 5 pih.setTarget(person); 6 Person proxy = (Person) pih.getProxy(); 7 person.rent(); 8 } 9 }