[Spring] dynamic agent

Dynamic agent

1, Dynamic agent

The Java dynamic proxy class is located in Java.lang.reflect Under package, the following two classes are generally involved:

1. Interface InvocationHandler: only one method is defined in the interface Object:invoke(Object obj,Method method,Object[] args). In practice, obj, the first parameter, generally refers to the proxy class, method is the method being proxied, and args is the parameter array of the method. This abstract method is implemented dynamically in a proxy class.

2. Proxy: this class is a dynamic proxy class, similar to the ProxySubject in the above example. It mainly includes the following contents:

Protected Proxy(InvocationHandler h): constructor, estimated to be used to assign internal H.

Static Class getProxyClass (ClassLoader loader,Class[] interfaces): obtain a proxy class, in which loader is the class loader and interfaces is an array of all interfaces owned by the real class.

Static object newproxyinstance (classloader, loader, class [] interfaces, invocationhandler h): returns an instance of the proxy class. The returned proxy class can be used as the proxy class (the methods of the proxy class declared in the Subject interface can be used).

2, Agency mechanism and characteristics

Create your own call processor by implementing the InvocationHandler interface;

Create a dynamic Proxy class by specifying a ClassLoader object and a set of interface s for the Proxy class;

Through the reflection mechanism, the constructor of dynamic proxy class is obtained. The only parameter type is the type of calling processor interface;

The dynamic proxy class instance is created through the constructor, and the call processor object is passed in as a parameter during construction.

3, Cases

3.1 static agent

3.1.1 concept

  • Enhance the function of the proxied class

3.1.2 steps

  • The custom class implements the same interface as the proxy class
  • Declare the object of the proxy class in the proxy class
  • Use the method called by the proxy class in the method of the proxy class

3.1.3 code

//Rental house
public interface Rent {

    void rent();
}
//landlord or landlady
public class Owner implements Rent{

    public void rent() {
        System.out.println("Rental house");
    }
}
//Intermediary (agent)
public class Proxy implements Rent{

    private Owner owner;

    public Proxy(Owner owner) {
        this.owner = owner;
    }

    public void rent() {
        seeHouse();
        owner.rent();
        cost();
    }

    public void seeHouse(){
        System.out.println("House watching with intermediary");
    }

    public void cost(){
        System.out.println("Intermediary charges");
    }

}
//Static agent
public class Test {

    public static void main(String[] args) {

        Owner owner = new Owner();
        owner.rent();

        System.out.println("---------------");

        Proxy proxy = new Proxy(owner);
        proxy.rent();
    }

}

3.2 case 2

public interface UserService {

    void add();
    void update();
}
public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("add...");
    }

    public void update() {
        System.out.println("update...");
    }
}
public class UserServiceProxy implements UserService{

    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    public void add() {
        log();
        userService.add();
    }

    public void update() {
        log();
        userService.update();
    }

    public void log(){
        System.out.println("Log...");
    }
}
public class Test {

    public static void main(String[] args) {

        UserServiceImpl userService = new UserServiceImpl();
        userService.add();
        userService.update();

        System.out.println("-------------------------");

        UserServiceProxy userServiceProxy = new UserServiceProxy();
        userServiceProxy.setUserService(userService);

        userServiceProxy.add();
        userServiceProxy.update();
    }
}

3.3 Proxy dynamic proxy

3.3.1 concept

  • Interface based method enhancement

3.3.2 code implementation

//Rental house
public interface Rent {

    void rent();

    void test();
}
//Landlord (real object)
public class Owner implements Rent{

    public void rent() {
        System.out.println("Rental house");
    }

    public void test() {
        System.out.println("test....");
    }
}
public class MyInvocationHandler implements InvocationHandler {

    private Rent rent;//Generate agent for

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //Returns an instance of a proxy class for a specified interface that can assign method calls to a specified call handler
    public Rent getProxy(){
        return (Rent) Proxy.newProxyInstance(rent.getClass().getClassLoader(),
                rent.getClass().getInterfaces(),this);
    }

    //Call method and return result
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("The current call is"+method.getName()+"method");
        seeHouse();
        Object result = method.invoke(rent, args);
        cost();
        return result;
    }


    public void seeHouse(){
        System.out.println("House watching with intermediary");
    }

    public void cost(){
        System.out.println("Intermediary charges");
    }

}
public class Test {
    public static void main(String[] args) {

        Owner owner = new Owner();

        MyInvocationHandler handler = new MyInvocationHandler();
        handler.setRent(owner);

        //Build agent
        Rent proxy = handler.getProxy();
        proxy.rent();
        proxy.test();
    }
}

3.4 general agent

//General implementation agent class
public class MyInvocationHandlerUtils implements InvocationHandler {

    private Object target;//Generate agent for

    public void setTarget(Object target) {
        this.target = target;
    }

    //Returns an instance of a proxy class for a specified interface that can assign method calls to a specified call handler
    public Object getProxy(){
        return  Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    //Call method and return result
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("The current call is"+method.getName()+"method");
        seeHouse();
        Object result = method.invoke(target, args);
        cost();
        return result;
    }


    public void seeHouse(){
        System.out.println("House watching with intermediary");
    }

    public void cost(){
        System.out.println("Intermediary charges");
    }
}
public class Test {
    public static void main(String[] args) {
    
        Owner owner = new Owner();
        MyInvocationHandlerUtils myInvocationHandlerUtils = new MyInvocationHandlerUtils();
        myInvocationHandlerUtils.setTarget(owner);

        Rent proxy = (Rent)myInvocationHandlerUtils.getProxy();
        proxy.rent();
        proxy.test();
    }
}

Tags: Java

Posted on Sun, 21 Jun 2020 04:51:44 -0400 by mohamdally