Principle analysis and code implementation of JDK dynamic proxy

The proxy is like: buyer (client) - sales (proxy object) - factory (target)

        Buyers don’t need to go directly to the factory to buy, but can buy directly through sales. Assuming that the factory produces cups, then the factory only needs to provide cups, and the sales will design the packaging of the cups without changing the production process of the cups. advertising. increase its sales.

      In the proxy mode , the proxy object acts as the middleman of the proxy object, and the client accesses the proxy object through the proxy object instead of directly accessing the proxy object. The main purpose is to provide additional functionality or control access without changing the original object. Enhanced code security and flexibility.

1. What is a dynamic proxy?

      The relationship between the proxy class and the proxied class has been determined in the static proxy at compile time, and the proxy class is manually written. In static proxies, a proxy class needs to be written for each proxied class. It needs to manually write proxy classes, which will lead to code redundancy when there are many proxy classes. So in this case we need to use dynamic proxy.

        Dynamic proxy dynamically generates proxy classes and proxy objects at runtime, without manually writing proxy classes. In dynamic proxy, the proxy class is dynamically generated through the reflection mechanism at runtime. The advantage of dynamic proxy is that it can reduce code redundancy. The disadvantage is that its implementation is slightly more complicated than that of static proxy.

2. Implementation of JDK dynamic proxy

        The following code example is to call the dance and rap methods of the star by calling the broker proxy object. The star is only responsible for the work, and the function of collecting money is added to the broker method.

Define the interface: I first defined a Star interface, which has two interfaces of dance and rap:

public interface Star {

    /**
     * 跳舞
     */
    public void dance();

    /**
     * 说唱
     */
    public void rap();
}

Create a Star interface implementation class: implement two methods in this class:

public class OnePeople implements Star{

    @Override
    public void dance() {
        System.out.println("我跳舞了");
    }

    @Override
    public void rap() {
        System.out.println("我唱了rap");
    }
}

Create an InvocationHandler implementation class :

//当调用代理对象的方法时,实际上是调用了invoke()方法。在invoke()方法中,可以根据需要执行一些前置或后置操作,然后将方法调用转发给实际的对象。
public class MyInvocationHandler implements InvocationHandler {
    //被代理对象
    Object object;
    public MyInvocationHandler (Object o){
        object = o;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我已经收好钱了,我的boss可以开始工作了");
        //通过反射调用被代理对象的方法。
        Object invoke = method.invoke(object, args);
        System.out.println("我们已经工作完毕,拍拍屁股离开");
        return invoke;
    }
}

Create a proxy object:

public class Demo {
    public static void main(String[] args) {
        OnePeople onePeople = new OnePeople();
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(onePeople);
        //newProxyInstance()接受三个参数:类加载器、要实现的接口列表和一个InvocationHandler对象
        // 返回的是实现指定接口的代理类的实例。这个实例可以被强制转换为接口类型,以便在代码中使用。
        Star star = (Star) Proxy.newProxyInstance(onePeople.getClass().getClassLoader(),
                onePeople.getClass().getInterfaces(), myInvocationHandler);
        //调用跳舞方法
        star.dance();
        //调用rap方法
        star.rap();
    }
}

operation result:

Note: JDK dynamic proxy can only proxy interfaces, not specific classes. If you want to proxy a specific class, you can consider using other proxy mechanism (CGLIB mechanism).

3. Advantages of dynamic proxy

  1. Flexibility: Dynamic proxies can create proxy objects at runtime, without the need to determine the type of proxy objects at compile time. This makes the dynamic proxy more flexible, and different types of proxy objects can be dynamically created as needed.

  2. Extensibility: Dynamic proxies can customize the behavior of proxy objects by implementing the InvocationHandler interface. By writing custom logic in InvocationHandler, additional operations can be performed before and after the method call of the proxy object, such as logging, performance monitoring, transaction management, etc. This scalability makes dynamic proxies useful in many scenarios.

  3. Low coupling: Dynamic proxy can separate the creation of proxy objects from the implementation of proxy logic, thereby achieving low coupling. The creation of proxy objects can be done by proxy factories or dependency injection containers, and the implementation of proxy logic can be done by InvocationHandler. This low coupling makes the code clearer, easier to maintain and expand.

  4. Dynamics: Dynamic proxies can dynamically modify the behavior of proxy objects at runtime. This means that the methods of the proxy object can be dynamically added, modified or deleted according to the needs, so as to realize more flexible proxy logic.

Guess you like

Origin blog.csdn.net/qq_64680177/article/details/132142832