Static Agent and Dynamic Agent

Proxy pattern: It is a design pattern that provides additional access to the target object, that is, access to the target object through the proxy object, so as to provide additional functional operations and expand the function of the target object without modifying the original target object.

In short: Enhance the code without modifying the source code

Static proxy

Write the static code directly, and you will understand it by reading the code.

public interface UserDao {
    public void save();
}
public class UserDaoImpl implements UserDao{
    @Override
    public void save() {
        System.out.println("Save data");
    }
}
public class UserDaoProxy implements UserDao{

    private UserDao userDao;

    public UserDaoProxy(UserDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void save() {
        System.out.println("Open a transaction");
        userDao.save();
        System.out.println("Transaction submission");
    }
}
public class Test {
    public static void main(String[] args) {
        UserDao userDao = new UserDaoProxy(new UserDaoImpl());
        System.out.println(userDao.getClass());
        userDao.save();
    }
}

test result

class com.UserDaoProxy
 Open a transaction
 Save data
 Transaction submission

It's easy to see its drawbacks from the above code:

1. Redundancy - Because the proxy object implements the same interface as the target object, it will produce too many proxy classes.
2. Not easy to maintain - once the interface is added, both the target object and the proxy object need to be modified.

Dynamic Agent

The main differences between static agent and dynamic agent are as follows:

1. Static proxy is implemented at compile time, and the proxy class after compilation is an actual class file.
2. Dynamic proxy is generated dynamically at runtime, that is, there is no actual class file after compilation, but class bytecode is generated dynamically at runtime and loaded into JVM.

Classification:

jdk dynamic proxy: an interface-based dynamic proxy (the proxy class implements at least one interface and cannot be used if not)
CGLib proxy: dynamic proxy based on subclasses (proxy class cannot be final class)

Let's briefly talk about JDK dynamic proxy
Create proxy objects - - - using the new ProxyInstance method in the Proxy class

    public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

Introduction of the parameters of the new Proxy Instance method

ClassLoader: Class Loader - It is used to load the bytecode of the proxy object, and the proxy object uses the same class loader, fixed writing.

Class [] bytecode array - It is used to make proxy objects and proxy objects have the same method, fixed writing

Invocation Handler is used to provide enhanced code -- let's write how to proxy

Here's an example (proxy class or above)

public class DynStaticFactory {

    private Object target;// Maintaining a target object

    public DynStaticFactory(Object target) {
        this.target = target;
    }
    // Generate proxy objects for target objects
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
		target.getClass().getInterfaces(), new InvocationHandler() {
            /**
             * Any interface method of the proxy object is executed through this method
             * @param proxy References to proxy objects
             * @param method Current method of execution
             * @param args The parameters needed to execute the current method
             * @return Have the same return value as the proxy object
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method,
			Object[] args) throws Throwable {
                System.out.println("Open a transaction");
                // Executing target object method
                Object returnValue = method.invoke(target, args);
                System.out.println("Submission transaction");
                return null;
            }
        });
    }
}

```java
public class TestDyn {
    public static void main(String[] args) {
        DynStaticFactory dynStaticFactory = new DynStaticFactory(new UserDaoImpl());
        UserDao userDao = (UserDao)dynStaticFactory.getProxyInstance();
        System.out.println(userDao.getClass());
        userDao.save();
    }
}

test result

class com.sun.proxy.$Proxy0
 Open a transaction
 Save data
 Submission transaction
Above are some of the summaries I have learned. There may be some inaccuracies or errors in what I said. I hope you can help me put them forward.

Keywords: JDK jvm Java

Added by KiwiDave on Mon, 12 Aug 2019 08:55:41 +0300