设计模式--代理模式

  代理模式是一种结构型设计模式,它可以为其他对象提供一种代理以控制对这个对象的访问。

  所谓的代理,是指具有与被代理对象相同的接口的类,客户端必须通过代理与被代理的目标类进行交互,而代理一般在交互的过程中(交互前后),进行某些特定的处理。


代理模式中的角色:

1.抽象对象角色

声明了目标类及代理类对象的共同接口,这样在任何可以使用目标对象的地方都可以使用代理对象。

2.目标对象角色

定义了代理对象所代表的目标对象。

3.代理对象角色

代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象和目标对象具有统一的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或者之后,执行某些操作,而非单纯的将调用传递给目标对象。

示例代码:

首先定义AbstractObject类,在其中定义代理类和目标类有公有的接口operation()

1 public abstract class AbstractObject{
2  protected abstract void operation();
3 }

目标实现类:

1 public class RealObject extends AbstractObject{
2 
3     @Override
4     protected void operation() {
5         System.out.println("do operation...");
6     }
7 }

代理类:

 1 package staticproxy;
 2 
 3 public class ProxyObject extends AbstractObject{
 4 
 5     private RealObject realObject;
 6     
 7     public ProxyObject(RealObject realObject) {
 8         this.realObject=realObject;
 9     }
10 
11     @Override
12     protected void operation() {
13         System.out.println("do something before real peration...");
14         if(realObject==null) {
15             realObject=new RealObject();
16         }
17         realObject.operation();
18         System.out.println("do something after real operation...");
19     }
20 }

测试类:

1 package staticproxy;
2 
3 public class ProxyTest {
4 
5     public static void main(String[] args) {
6         AbstractObject proxy = new ProxyObject(new RealObject());
7         proxy.operation();
8     }
9 }

 执行结果:

 总结:

代理模式的使用场景:

如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种方法:

(1)修改原有的方法来适应。

(2)采用一个代理类调用原来的方法,且对产生的结果进行控制。

使用代理模式可以将功能划分的更加清晰,有助于后期的维护。

以上所说的这种代理模式称为静态代理

动态代理(也叫JDK代理)

jdk中的动态代理通过反射类Proxy和InvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际边中有一定的局限性。

见另一篇

Cglib代理

使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码。

https://www.cnblogs.com/chinajava/p/5880887.html----cglib动态代理解释

前提条件:

*需要引入cglib的jar文件,由于Spring的核心包中已经包括了Cglib功能,所以也可以直接引入spring-core-3.2.5.jar

*目标类不能为final

*目标对象的方法如果为final/static,那么就不会拦截,即不会执行目标对象额外的业务方法

cglib的jar包---cglib-nodep-2.2.2.jar

目标对象,没有实现任何接口 Singer.java

 1 package CglibProxy;
 2 //目标对象,没有实现任何接口
 3 public class Singer {
 4     public void sing() {
 5         System.out.println("唱一首歌");
 6     }
 7     public void myname() {
 8         System.out.println("我叫彭于晏");
 9     }
10 }

子类代理工厂--ProxyFactory.java

 1 //Cglib子类代理工厂
 2 public class ProxyFactory implements MethodInterceptor{
 3 
 4     //维护目标对象
 5     private Object target;
 6     //构造函数
 7     public ProxyFactory(Object target) {
 8         this.target=target;
 9     }
10     
11     //创建代理类对象
12     public Object getProxyInstance() {
13         //1.工具类
14         Enhancer en=new Enhancer();
15         //2.设置父类
16         en.setSuperclass(target.getClass());
17         //3.设置回调函数
18         en.setCallback(this);
19         //4.创建子类(代理对象)
20         return en.create();
21     }
22     
23     //重写的方法        拦截
24     @Override
25     public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
26         System.out.println("向观众问好");
27         //执行目标对象的方法
28         Object returnValue=arg1.invoke(target, arg2);
29         System.out.println("谢谢大家");
30         return returnValue;
31     }
32 }

这里的代码也非常固定,只有标黄部分是需要自己写出

测试

 1 package CglibProxy;
 2 
 3 public class Test {
 4     public static void main(String[] args) {
 5         //目标对象
 6         Singer target=new Singer();
 7         //代理对象
 8         Singer proxy=(Singer)new ProxyFactory(target).getProxyInstance();
 9         //执行代理对象的方法
10         proxy.myname();
11         proxy.sing();
12     }
13 }
原文地址:https://www.cnblogs.com/xjs1874704478/p/10741743.html