(1)什么是代理?java
大道理上讲代理是一种软件设计模式,目的地但愿能作到代码重用。具体上讲,代理这种设计模式是经过不直接访问被代理对象的方式,而访问被代理对象的方法。这个就比如 商户---->明星经纪人(代理)---->明星这种模式。咱们能够不经过直接与明星对话的状况下,而经过明星经纪人(代理)与其产生间接对话spring
(2)什么状况下使用代理?设计模式
a. 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,咱们在工做中有时会接手不少前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时咱们就能够经过代理对类进行加强。
b. 咱们在使用RPC框架的时候,框架自己并不能提早知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用经过动态代理的方式来创建一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。框架
(3)静态代理和动态代理
静态代理比较简单,主要是多态实现,这里主要记录下动态代理ide
定义代理父类测试
package cn.crawler.split.test.proxy; /** * Created by liang.liu04@hand-china.com * on 2018/7/12 */ public interface Father { public void rent(); public void hello(String str); }
子类this
/** * Created by liang.liu04@hand-china.com * on 2018/7/12 */ public class Son implements Father { @Override public void rent() { System.out.println("I want to rent my house"); } @Override public void hello(String str) { System.out.println("hello: " + str); } }
代理类设计
package cn.crawler.split.test.proxy; import org.springframework.cglib.proxy.InvocationHandler; import java.lang.reflect.Method; /** * Created by liang.liu04@hand-china.com * on 2018/7/12 */ public class DynamicProxy implements InvocationHandler { // 这个就是咱们要代理的真实对象 private Object subject; // 构造方法,给咱们要代理的真实对象赋初值 public DynamicProxy(Object subject) { this.subject = subject; } @Override public Object invoke(Object object, Method method, Object[] args) throws Throwable { // 在代理真实对象前咱们能够添加一些本身的操做 System.out.println("before rent house"); System.out.println("Method:" + method); // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 method.invoke(subject, args); // 在代理真实对象后咱们也能够添加一些本身的操做 System.out.println("after rent house"); return null; } }
测试类3d
package cn.crawler.split.test.proxy; import org.springframework.cglib.proxy.InvocationHandler; import org.springframework.cglib.proxy.Proxy; /** * Created by liang.liu04@hand-china.com * on 2018/7/12 */ public class MyProxyTest { public static void main (String[] stra){ //代理对象 Father son = new Son(); System.out.println(son.getClass()); InvocationHandler handler = new DynamicProxy(son); Father father = (Father)Proxy.newProxyInstance(handler.getClass().getClassLoader(), son.getClass().getInterfaces(), handler); System.out.println(father.getClass().getName()); father.rent(); father.hello("world"); } }
测试结果:代理
class cn.crawler.split.test.proxy.Son org.springframework.cglib.proxy.Proxy$ProxyImpl$$EnhancerByCGLIB$$f4f3d897 before rent house Method:public abstract void cn.crawler.split.test.proxy.Father.rent() I want to rent my house after rent house before rent house Method:public abstract void cn.crawler.split.test.proxy.Father.hello(java.lang.String) hello: world after rent house