JAVA about static proxy and JDK dynamic proxy

About static proxy and JDK dynamic proxy

what is a proxy

In layman's terms, an agent is to do something on behalf of someone. For example, if a teacher is sick and cannot come to class today, is it possible to hire an acting teacher to help with the class? In a practical sense, the two teachers The finished things are the same, they are all for the students to preach and learn, but can the acting teacher expand more "functions" on the basis of the original class , for example, before the acting teacher goes to the class, he first goes to the next class to see Did the female teacher I like at a glance come, and after class, I went to eat my favorite snail noodles~ Seeing here, do you feel that it looks like a thing, so the principle of SpringAOP’s aspect-oriented transformation is like this, of course The actual implementation aspect is more complicated.

Agents are divided into three roles

  1. interface
  2. delegate class
  3. Proxy class

static proxy

Let's talk about static proxy first, and use the example we gave earlier to directly upload the code.

interface:

package com.staticproxy;

//我和代理老师都是老师,共同实现了老师接口
public interface Teacher {
    
    
   void teach();
}

Delegating class:

package com.staticproxy;
//这个就是生病的老师
public class MathTeacher implements Teacher {
    
    
   @Override
   public void teach() {
    
    
       System.out.println("传道受业解惑40分钟");
   }
}

Proxy class:

package com.staticproxy;
//这个是代理老师
public class ProxyTeacher implements Teacher {
    
    
   //通过构造器注入被代理对象(注入一个生病老师的对象)
   private Teacher targetTeacher;
   public ProxyTeacher(Teacher teacher){
    
    
       this.targetTeacher=teacher;
   }

   //代理老师实现了接口也有teach方法
   @Override
   public void teach() {
    
    
       System.out.println("上课之前先去隔壁班看美女老师");
       //调用生病老师的teach方法
       targetTeacher.teach();
       System.out.println("上完课了,去吃个螺蛳粉压压惊!");
   }
}

Client's main method:

package com.staticproxy;

public class Client {
    
    
   public static void main(String[] args) {
    
    
       Teacher teacher=new MathTeacher();
       Teacher proxyteacher=new ProxyTeacher(teacher);
       proxyteacher.teach();
   }
}

Result:
insert image description here
The static proxy should be cleared up quickly, very simple.
Let's continue with the dynamic proxy, which requires the reflection mechanism.

JDK dynamic proxy

interface:

package com.jdkproxy;

public interface Teacher {
    
    
   void teach();
}

Nothing to say about the same interface as before

Delegating class:

package com.jdkproxy;

public class MathTeacher implements Teacher {
    
    
   @Override
   public void teach() {
    
    
       System.out.println("传道受业解惑40分钟");
   }
}

Here comes the point

package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* 注意动态代理这里不需要再实现教师接口了
* 这样才能体现动态的概念,往往在实际应用之中
* 我们是不会提前知道我们需要代理什么对象的
*/
public class ProxyTeacher {
    
    

   private Object targetteacher;
   public ProxyTeacher(Teacher teacher){
    
    
       this.targetteacher=teacher;
   }

/**
* 这里调用了Proxy的newProxyInstance方法获得代理对象
* 参数1表示被代理对象的类加载器
* 参数2是被代理对象实现的接口,可以是数组(表示实现多个接口)
* 参数3是用匿名内部类实例化一个实现了InvocationHandler接口的对象
*/
   public Object getProxyInstance(){
    
    
       return Proxy.newProxyInstance(targetteacher.getClass().getClassLoader(), targetteacher.getClass().getInterfaces(),
               new InvocationHandler() {
    
    
                   /**
                   * @param proxy 调用这个方法的代理实例
    			   * @param method 要调用的方法
    			   * @param args 方法调用时所需要的参数
    			   * @return 方法调用的结果
   				   */
   				   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
                       System.out.println("上课之前先去隔壁班看美女老师");
                       method.invoke(targetteacher,args);
                       System.out.println("上完课了,去吃个螺蛳粉压压惊");
                       return null;
                   }
               });
   }
}

Client:

package com.jdkproxy;

public class Client {
    
    
   public static void main(String[] args) {
    
    
       Teacher teacher=new MathTeacher();
       Teacher proxyTeacher=(Teacher)new ProxyTeacher(teacher).getProxyInstance();
       proxyTeacher.teach();
   }
}

Result:
insert image description here
Summary:
Of course, the dynamic proxy used by SpringAop is more complicated, and other technologies such as cglib dynamic proxy are not extended here. We only need to know that the dynamic proxy can continue to extend and integrate on the basis of completing the functions realized by the original object. Expansion, which is also an important idea of ​​SpringAop's aspect-oriented programming, is widely used in functions such as logging, exception handling, monitoring, and transaction management. This is the general principle of aspect-oriented. You can think of it this way. Classes are a must-do process for teachers. In this process, the two functions of looking at beauties and eating are cut horizontally, without affecting the realization of the functions at all.

Guess you like

Origin blog.csdn.net/chenyingchuan996/article/details/105254918
Recommended