Java implements a simple interceptor through a dynamic proxy

1. Agency

Before using dynamic proxies to implement interceptors, let's take a brief look at what Java proxies are.

A proxy, as its name implies, does not directly operate on the object to which it is proxied (referred to below as the target object, which sounds more comfortable), but indirectly uses the methods in the target object through a proxy object.There are two modes of proxy, one is static proxy and the other is dynamic proxy.Let's start with an example of a static proxy.

The target implements an interface whether it is a static or a dynamic proxy. Note that if you use the proxy provided by cglib, you do not have to implement the interface, but rather implement it through subclasses, which is not discussed yet.

(1) Define an interface first

public interface IUserDao {
    void save();
}

(2) Define the target object

public class UserDaoImpl implements IUserDao {
    public void save() {
        System.out.println("--------Saved data---------");
    }
}

(3) Defining proxy objects

public class UserDaoProxy implements IUserDao {
    private IUserDao target;//Place the target object in the proxy object
    public UserDaoProxy(IUserDao target){
        this.target = target;
        }
    public void save() {
        System.out.println("------Start Transaction------");
            target.save();
        System.out.println("-------Submit Transaction------");
    }
}

Test it:

public class Test {
public static void main(String[] args){
    IUserDao userDao = new UserDaoImpl();
    UserDaoProxy proxy = new UserDaoProxy(userDao);
    proxy.save();//Call save method through proxy object
    }
}

The output is:

-------------------------------
-------------------------------------

--------------------------------------------------------------------------------------------------------------------

The problem with this approach is that the proxy object must also implement the same interface that the proxy object implements, which results in severe coupling.So here's an improved way to use dynamic proxy (jdk proxy).

Dynamic proxy also requires a target to implement an interface

(1) Define an interface (IUserDao)

(2) Define a target object class (UserDaoImpl)

(3) Create dynamic proxy classes

public class ProxyFactory {
    //Maintain a target object
    private Object target;
 
    public ProxyFactory(Object target) {
        this.target = target;
    }
 
    //Generate proxy object for target object
    public Object getProxyInstance() {
        System.out.println("----target class---" + target.getClass());
        System.out.println("----target interfaces---" +
            target.getClass().getInterfaces());
 
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                    System.out.println("----Start Transaction 2-----");
 
                    //Execute Target Object Method
                    Object returnValue = method.invoke(target, args);
                    System.out.println("----Commit Transaction 2----");
 
                    return returnValue;
                }
            });
    }
}

Test it:

public class Test {
    public static void main(String[] args) {
        //Target object
        IUserDao target = new UserDaoImpl();
        System.out.println(target.getClass());
 
        //Create a proxy object for the target object
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
        System.out.println("----proxy----: " + proxy.getClass());
        proxy.save();
        proxy.delete();
    }
}

Output results:

class com.jd.pattern.proxy.dynamicProxy.UserDao
----target class---class com.jd.pattern.proxy.dynamicProxy.UserDao
----target interfaces---[Ljava.lang.Class;@1fb3ebeb
----proxy----: class com.sun.proxy.$Proxy0
----Start Transaction 2-----
-----Save Complete------
----Commit Transaction 2----
----Start Transaction 2-----
----Delete complete----

----Commit Transaction 2----

2. Implement a simple interceptor using dynamic proxy

Now that you are using dynamic proxy, there must be interfaces, target classes, proxy classes, plus an interceptor

1. Define an interface

public interface BusinessFacade {
    void doSomething();
}

2. Define a target object

public class BusinessClass implements BusinessFacade {
    public void doSomething() {
        System.out.println("In Business Components BusinessClass Called in doSomething Method");
    }
}

3. Create interceptors

public class InterceptorClass {
    public void before() {
        System.out.println("stay InterceptorClass Call method in: before()");
    }
 
    public void after() {
        System.out.println("stay InterceptorClass Call method in: after()");
    }
}

4. Create proxy

public class DynamicProxyHandler {
    //Declare Proxy Object
    private Object target;
    //Create Interceptor
    InterceptorClass interceptor = new InterceptorClass();
    //Dynamically generates a proxy object and binds the proxy class and proxy processor
    public Object getProxyInstance(final Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                    interceptor.before();
                    Object result = method.invoke(target, args);
                    interceptor.after();
                    return result;
                }
            });
    }
}

Test it:

public class Test {
    public static void main(String[] args) {
        //Create Dynamic Proxy Tool
        DynamicProxyHandler proxyHandler = new DynamicProxyHandler();
        //Create business components
        BusinessFacade target = new BusinessClass();
        //Get Proxy Object
        BusinessFacade proxy = (BusinessFacade) proxyHandler.getProxyInstance(target);
        //Call target object method through proxy object
        proxy.doSomething();
    }
}

Output results:

Call method in InterceptorClass: before()
Calling the doSomething method in the business component BusinessClass
Call method in InterceptorClass: after()
--------
Copyright Notice: This is an original article by CSDN blogger "Li Bai csdn". It is reproduced in accordance with the CC 4.0 BY-SA copyright agreement. Please attach a link to the original source and this statement.
Original link: https://blog.csdn.net/zjl_pcw/article/details/80505114

Twenty-four original articles have been published. 64. 20,000 visits+
Private letter follow

Tags: Java JDK

Posted on Sat, 18 Jan 2020 21:08:25 -0500 by smallflower