设计模式-代理模式

代理模式

  代理模式是属于结构模式之一。该模式的作用主要是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接使用另一个对象,此时代理对象可以在客户端和目标对象之间起到中介的作用。

  代理模式的实现方式有静态代理、jdk动态代理和cglib动态代理。

静态代理

  静态代理是指在程序运行前代理类的.class文件就已经存在,是由程序员在编码时手动实现的。

  示例如下:

定义一个接口

1
2
3
4
5
public interface Person {

void speak();

}

实现类

1
2
3
4
5
6
7
8

public class Actor implements Person {

@Override
public void speak() {
System.out.println("这是actor");
}
}

代理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

public class Agent implements Person {

private Actor actor;

public Agent(Actor actor) {
this.actor = actor;
}

@Override
public void speak() {
System.out.println("进入代理");
actor.speak();
System.out.println("退出代理");
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14

public class StaticProxyTest {
public static void main(String[] args) {
Actor actor = new Actor();
Agent agent = new Agent(actor);
agent.speak();
}
}

/**
进入代理
这是actor
退出代理
**/

jdk动态代理

  jdk动态代理与静态代理最大的区别就是代理类的.class文件是在运行时生成的,而且被代理类必须要实现一个接口。

  示例如下,接口和被代理类和静态代理一样

代理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public class JdkProxy implements InvocationHandler {

private Actor actor;

public JdkProxy(Actor actor) {
this.actor = actor;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理");
method.invoke(actor, args);
System.out.println("退出代理");
return null;
}

public Object getProxy() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), this.actor.getClass().getInterfaces(), this);
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

public static void main(String[] args) {
Actor actor = new Actor();
JdkProxy jdkProxy = new JdkProxy(actor);
Person proxy = (Person) jdkProxy.getProxy();
proxy.speak();
}

/**

进入代理
这是actor
退出代理

**/

cglib动态代理

  cglib是一个功能强大的代码生成包,其底层依赖asm框架。cglib实现动态代理最大的特点就是被代理类不需要实现接口。

  示例如下

被代理类

1
2
3
4
5
6
7
public class ActorNoInterface {

public void speak() {
System.out.println("我是actor没有实现接口");
}

}

代理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

public class CglibProxy implements MethodInterceptor {

private Object actor;

public CglibProxy(ActorNoInterface actor) {
this.actor = actor;
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("进入cglib代理");
methodProxy.invokeSuper(o, objects);
System.out.println("退出cglib代理");
return null;
}

public Object getInstance() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.actor.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
}

测试

1
2
3
4
5
6
7
8

public class CglibProxyTest {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy(new ActorNoInterface());
ActorNoInterface actor = (ActorNoInterface) cglibProxy.getInstance();
actor.speak();
}
}
-------------本文结束感谢您的阅读-------------

本文标题:设计模式-代理模式

文章作者:小建儿

发布时间:2018年08月13日 - 12:08

最后更新:2018年08月13日 - 12:08

原始链接:http://yajian.github.io/设计模式-代理模式/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。