(1)什么是代理?
大道理上讲代理是一种软件设计模式,目的地希望能做到代码重用。具体上讲,代理这种设计模式是通过不直接访问被代理对象的方式,而访问被代理对象的方法。这个就好比 商户---->明星经纪人(代理)---->明星这种模式。我们可以不通过直接与明星对话的情况下,而通过明星经纪人(代理)与其产生间接对话
(2)什么情况下使用代理?
a. 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时我们就可以通过代理对类进行增强。
b. 我们在使用RPC框架的时候,框架本身并不能提前知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用通过动态代理的方式来建立一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。
(3)静态代理和动态代理
静态代理比较简单,主要是多态实现,这里主要记录下动态代理
定义代理父类
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);
}
子类
/**
* 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;
}
}
测试类
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。