Detailed explanation of jdk dynamic proxy of java proxy mode (super detailed)

Agent mode:

Proxy is one of the basic design patterns, it provides you with additional or different operations, and the inserted object is used to proxy the "real" object. These operations usually involve communication with the "real" object, so the proxy usually acts as The role of the middleman.

Dynamic proxy

Dynamic proxy does not need to care about the proxy class in the implementation phase, but specifies which object in the runtime phase.
The advantages of dynamic proxy:

  • Clear responsibilities The
    real role is to realize the actual business logic. You do not need to care about other non-responsible transactions. You can complete the transaction through a later agent. The incidental result is simple and clear programming.
  • The proxy object can act as an intermediary between the client and the target object, which acts as an intermediary and protects the target object. That is, you can enhance the function without modifying the target object.
  • High scalability, you can add the functions you need to the methods you need.

Implement dynamic proxy based on jdk:

Java.lang.reflect.Proxy is provided in the API of jdk. It can help us to complete the creation of dynamic proxy.
Note: The use of Proxy in java to complete the creation of dynamic proxy objects can only create proxy objects for the classes that implement the interface.
Dynamic proxy is to generate proxy object directly in memory.
Insert picture description hereContinue to look at the api:
Insert picture description heregenerally we use this method to construct the proxy object, which requires three parameters:

  1. ClassLoader loader:

Insert picture description hereThe translation is: each Class object contains a reference to the ClassLoader that defines it. The class object of the array class is not created by the class loader, but automatically created according to the needs of the Java runtime. The class loader of the array class returned by Class.getClassLoader () is the same as the class loader of its element type; if the element type is a basic type, the array class has no class loader. So as long as the object we need to proxy is not an array, we can use the getClassLoader () of the Class object to get the ClassLoader object;

  1. Class<?>[] interfaces:

Insert picture description hereThere is this method in the class class, which can be obtained directly. This class represents the interface implemented by the target object

  1. InvocationHandler h:
    Click to find that this is an interface, there is an unimplemented invoke (…) method.
    Insert picture description here
    Insert picture description hereThat is to say, the object that needs to be passed in here needs to implement this interface, and the invoke () method needs to be completed, explained below Three parameters in this method:
  • Parameter 1: Object proxy, this is the object we want to proxy

  • Parameter 2: Method method: the target behavior we need to access, that is, the method we need to call

  • Parameter 3: Object [] args: parameters required when calling behavior

The main function of this method is to control whether the target behavior can be called when we call the behavior through the proxy object.
The following is implemented with code:

//接口
public interface IUserService {
	public String addUser(String username,String password);
}
//实现类
public class UserServiceImpl implements IUserService {
	@Override
	public String addUser(String username, String password) {
		System.out.println("添加用户:" + username + "   " + password);
		return "hello " + username;
	}
}

Now we have to write a proxy class to proxy UserServiceImpl:

public class UserServiceProxy implements InvocationHandler {
    // 目标对象
    private Object target;
    public UserServiceProxy(Object target) {
        this.target = target;
    }
    // 作用:创建代理对象
    public Object createProxy() {
        ClassLoader loader = target.getClass().getClassLoader();
        Class[] interfaces = target.getClass().getInterfaces();
        return Proxy.newProxyInstance(loader, interfaces, this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method);
        System.out.println(Arrays.asList (args));
        System.out.println("方法调用之前");
        Object result = method.invoke (target,args);
        System.out.println("方法调用之后");
        return result;
    }
}

Next write a test class:

public class Test {
    public static void main(String[] args) {
        //需要代理的对象
        IUserService userservice = new UserServiceImpl ();
        //创建代理类
        UserServiceProxy up =  new UserServiceProxy(userservice);
        IUserService proxy = (IUserService) up.createProxy ();
        //使用代理类进行方法增强
        String s = proxy.addUser ("tom", "123");
        System.out.println("s: " + s);
    }
}

Output result:
Insert picture description here
The output is analyzed below: the
first output is the method object, which points to IUserService.addUser, and the second is the third parameter in invoke (), which is actually the parameter we use when using the proxy object (The first parameter is generally not used), and then before and after the addUser () method, we also added our custom content, and also obtained the return value of the method call.

to sum up:

  1. Dynamic proxy is a proxy method that does not need to care about the proxy class in the implementation phase, but specifies which object in the runtime phase.
  2. The dynamic proxy method of jdk is to use the Proxy.newProxyInstance (ClassLoader loader, Class <?> [] interfaces, InvocationHandler h) method to generate a proxy object. The third parameter requires the proxy class to implement the InvocationHandler interface and implement the invoke () method, and finally use The agent class performs method enhancement.
  3. In development, we use dynamic proxies to complete operations such as performance monitoring, permission control, and logging. Spring's AOP is partially implemented using jdk's dynamic proxies.
Published 39 original articles · won praise 1 · views 4620

Guess you like

Origin blog.csdn.net/thetimelyrain/article/details/96383180