Proxy mode of Java design pattern, Java static proxy, Java Dynamic Proxy

Proxy mode of Java design pattern, Java static proxy, Java Dynamic Proxy

 

================================

© Copyright sweet potato Yao 2021-06-21

https://blog.csdn.net/w995223851

 

1, Java static proxy

1. Define interface

 

public interface IHouse {

    //Sell the house
    void sale();
    
    //View house information
    String house();
}

 

 

2. Proxied object class (actual operation class)

 

public class HouseOwner implements IHouse {

    @Override
    public void sale() {
        System.out.println(". . . I sold my house");
    }

    @Override
    public String house() {
        return "The house is in Futian, Shenzhen. Price: 1.2 Hundred million";
    }

}

 

 

3. Agent class

 

public class HouseProxy implements IHouse {

    //Proxied object
    private HouseOwner houseOwner;
    
    public HouseProxy(HouseOwner houseOwner) {
        this.houseOwner = houseOwner;
    }

    @Override
    public void sale() {
        System.out.println("[What did the agent do before selling the house");
        houseOwner.sale();
        System.out.println("[How much commission do you charge after selling");
    }

    @Override
    public String house() {
        return houseOwner.house();
    }

}

 

 

4. Testing

 

public class ProxyStatic {

    public static void main(String[] args) {
        
        HouseProxy houseProxy = new HouseProxy(new HouseOwner());
        houseProxy.sale();
        
        System.out.println("==============================");
        System.out.println(houseProxy.house());
        
    }
}

 

 

result:

[What did the agent do before selling the house
. . . I sold my house
[How much commission do you charge after selling
==============================
The house is in Futian, Shenzhen. Price: 1.2 Hundred million

 

 

 

2, Java} Jdk dynamic proxy

1. Dynamic proxy class

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyFactoryJdk{
    
    private Object proxyTarget;

    public DynamicProxyFactoryJdk(Object proxyTarget) {
        this.proxyTarget = proxyTarget;
    }
    
    
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(), proxyTarget.getClass().getInterfaces(), new InvocationHandler() {
            
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                
                System.out.println("jdk Dynamic agent start");
                System.out.println("method.getName()="+ method.getName());
                Object returnObject = method.invoke(proxyTarget, args);//This is a proxyTarget object, not a proxy parameter
                System.out.println("jdk Dynamic agent end.");
                
                return returnObject;
            }
        });
    }
    
    

}

 

2. Testing

public class ProxyDynamicJdk {

	public static void main(String[] args) {
		
		//An object must be declared using an interface
		IHouse proxyTarget = new HouseOwner();
		
		//An object must be declared using an interface
		IHouse houseProxy = (IHouse) new DynamicProxyFactoryJdk(proxyTarget).getProxyInstance();
		
		System.out.println("+++++++++++++++++++++++++++++++");
		System.out.println("houseProxy=" + houseProxy);
		System.out.println("houseProxy.getClass().getName()=" + houseProxy.getClass().getName());
		
		System.out.println("==============================");
		
		houseProxy.sale();
		
		System.out.println("==============================");
		System.out.println(houseProxy.house());
		
		
	}
}

 

result:

+++++++++++++++++++++++++++++++
jdk Dynamic agent start
method.getName()=toString
jdk Dynamic agent end.
houseProxy=com.lqy.springCloud.zzjava.designPattern.proxy.HouseOwner@6bc7c054
houseProxy.getClass().getName()=com.sun.proxy.$Proxy0
==============================
jdk Dynamic agent start
method.getName()=sale
. . . I sold my house
jdk Dynamic agent end.
==============================
jdk Dynamic agent start
method.getName()=house
jdk Dynamic agent end.
The house is in Futian, Shenzhen. Price: 1.2 Hundred million

 

 

3, Java cglib dynamic proxy

1. Dynamic proxy class (cglib related packages need to be introduced)

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

 

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * cglib package needs to be introduced
 *
 */
public class DynamicProxyFactoryCglib implements MethodInterceptor{
    
    private Object proxyTarget;

    public DynamicProxyFactoryCglib(Object proxyTarget) {
        this.proxyTarget = proxyTarget;
    }
    
    
    public Object getProxyInstance() {
        return Enhancer.create(proxyTarget.getClass(), this);
    }


    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        
        System.out.println("cglib Dynamic agent start");
        System.out.println("method.getName()="+ method.getName());
        Object returnObject = method.invoke(proxyTarget, args);//This is a proxyTarget object, not an obj parameter
        System.out.println("cglib Dynamic agent end.");
        
        return returnObject;
    }
    
    

}

 

 

2. Testing

public class ProxyDynamicCglib {

    public static void main(String[] args) {
        
        HouseOwner houseOwner = (HouseOwner) new DynamicProxyFactoryCglib(new HouseOwner()).getProxyInstance();
        
        System.out.println("+++++++++++++++++++++++++++++++");
        System.out.println("houseOwner=" + houseOwner);
        System.out.println("houseOwner.getClass().getName()=" + houseOwner.getClass().getName());
        
        System.out.println("==============================");
        
        houseOwner.sale();
        
        System.out.println("==============================");
        System.out.println(houseOwner.house());
        
        
    }
}

 

result:

+++++++++++++++++++++++++++++++
cglib Dynamic agent start
method.getName()=toString
cglib Dynamic agent end.
houseOwner=com.lqy.springCloud.zzjava.designPattern.proxy.HouseOwner@6842775d
houseOwner.getClass().getName()=com.lqy.springCloud.zzjava.designPattern.proxy.HouseOwner$$EnhancerByCGLIB$$8067e885
==============================
cglib Dynamic agent start
method.getName()=sale
. . . I sold my house
cglib Dynamic agent end.
==============================
cglib Dynamic agent start
method.getName()=house
cglib Dynamic agent end.
The house is in Futian, Shenzhen. Price: 1.2 Hundred million

 

 

4, Summary

 

Static proxy:

The implementation is relatively simple. As long as a proxy object is declared to wrap the target object, the proxy function can be realized, but the static proxy can only serve one target object. If there are too many target objects, many proxy classes will be generated.

Static agent generates class bytecode file during compilation, which can be used directly and has high efficiency.


JDK dynamic agent:

The target object needs to implement the business interface (the target class and proxy class must implement the same interface), and the proxy class only needs to implement the InvocationHandler interface.
The dynamic agent must implement the InvocationHandler interface. By reflecting the agent method, the system performance is consumed, but the number of agent classes can be reduced and the use is more flexible.

 

cglib dynamic proxy:

cglib (Code Generation Library) is a third-party code generation class library, which dynamically generates a subclass object in memory at runtime, so as to expand the function of the target object.

Using cglib requires introducing the jar package of cglib
Cglib proxy does not need to implement the interface. It implements the proxy by generating class bytecode, which is slightly faster than reflection, and there is no performance problem. However, cglib inherits the target object and needs to rewrite the method, so the target object cannot be final.

The object using cglib proxy does not need to implement the interface, so that the proxy class does not invade.

 

 

================================

© Copyright sweet potato Yao 2021-06-21

https://blog.csdn.net/w995223851

Keywords: Java

Added by djalecc on Fri, 28 Jan 2022 03:46:49 +0200