跳转至

代理模式

时间:2017-08-07 22:01:33

参考 :

  1. 《设计模式之禅(第二版)》-- 秦小波
  2. 《Java编程思想(第四版)》-- Bruce Eckel

代理模式 (Proxy Pattern)#

1
Provide a surrogate or placeholder for another object to control access to it;

为其他对象提供一种代理以控制对这个对象的访问。

普通代理#

代理类实现和被代理类相同的接口,通过代理类可以控制对被代理类的访问。

动态代理#

Java原生动态代理#

Human:

1
2
3
4
5
6
7
8
public interface Human {

    public void eat();

    public void sleep();

    public void drink();
}

Father:

1
public class Father implements Human {


@Override public void eat() { System.out.println(getClass().getSimpleName() + "eating ..."); }

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    @Override
    public void sleep() {
        System.out.println(getClass().getSimpleName() + "sleeping ...");
    }

    @Override
    public void drink() {
        System.out.println(getClass().getSimpleName() + "drinking ...");
    }
}

HumanInvocationHandler:

1
2
3
4
5
6
7
public class HumanInvocationHandler<T extends Human> implements InvocationHandler {

    private T proxyHuman;

    public HumanInvocationHandler(T proxyHuman) {
        this.proxyHuman = proxyHuman;
    }


@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //可以封装参数,预处理,插入日志等 String methodName = method.getName(); beforeInvoke(methodName); Object result = method.invoke(proxyHuman, args); afterInvoke(methodName); return result; }

1
2
3
    private void beforeInvoke(String methodName) {
        System.out.println("begin:    " + methodName);
    }


private void afterInvoke(String methodName){ System.out.println("end: " + methodName); } }

Family:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class Family {

    public static void main(String[] args) {
        Human father = new Father();
        HumanInvocationHandler humanInvocationHandler = new HumanInvocationHandler(father);

        Human proxyFather = (Human) Proxy.newProxyInstance
                (
                        father.getClass().getClassLoader(),
                        father.getClass().getInterfaces(),
                        humanInvocationHandler
                );

        proxyFather.eat();
        proxyFather.sleep();
        proxyFather.drink();
    }
}

cglib动态代理#

CglibService:

1
2
3
4
5
6
7
public interface CglibService {

    public void method1();

    public void method2();

}

CglibServiceImpl:

1
public class CglibServiceImpl implements CglibService {


@Override public void method1() { System.out.println("method1..."); }

1
2
3
4
5
    @Override
    public void method2() {
        System.out.println("method2...");
    }
}

CglibProxy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class CglibProxy implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("before: " + methodProxy.getSuperName());
        System.out.println("methodName: " + method.getName());
        Object result = methodProxy.invokeSuper(o, args);
        System.out.println("after: " + methodProxy.getSuperName());
        return result;
    }
}

Proxy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public class Proxy {

    public static void main(String[] args) {

        while (true){
            CglibProxy cglibProxy = new CglibProxy();
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(CglibServiceImpl.class);
            enhancer.setCallback(cglibProxy);

            CglibService cglibService = (CglibService) enhancer.create();
            cglibService.method1();
            cglibService.method2();
        }

    }
}