Design mode four, agency mode

The proxy mode provides a proxy for other objects to control access to this object.

Static proxy : The
principal and the agent implement the same interface, the principal holds an instance of the agent, and can do other things in the process of the agent task, such as
remote agent: provide a local representative for an object in different address spaces, Hide the fact that an object has different address spaces.

The virtual agent creates expensive objects as needed, and uses it to store real objects that take a long time to instantiate. For example, if the image is not loaded when the webpage is opened, the agent stores the path and size of the real image at this time.

Security agent, used to control the access rights of real objects.

Intelligent guidance, the agent handles other things. For example, count the number of references to a real object, and release the object when there is no reference. Before accessing an object, check whether it has been locked so that other objects cannot change it. When referencing a persistent object for the first time, load it into memory and so on.

When using a static proxy, you need to define an interface or a parent class, and the proxy object and the proxy object implement the same interface or inherit the same parent class.

//接口
public interface I {
    
    
    void operation();
}

//委托类
public class Subject implements I{
    
    
    @Override
    public void operation() {
    
    
        System.out.println("我是委托者");
    }
}

//代理类
public class ProxyMan implements I {
    
    
    I i;

    public ProxyMan(I i) {
    
    
        this.i = i;
    }

    @Override
    public void operation() {
    
    
        System.out.println("我是代理者,执行了代理");
        i.operation();
    }

    public static void main(String[] args) {
    
    
        gdut.iot.softdev.review.pattern.proxy.simple.Subject subject = new Subject();
        ProxyMan proxyMan = new ProxyMan(subject);
        proxyMan.operation();
    }
}

Dynamic proxy :

1. JDK characteristic proxy
proxy class is not defined in Java code, but is generated during runtime according to some instructions

  • It is very convenient to manage the functions of the proxy class in a unified way, without modifying the method one by one
  • The agency relationship is not hard-coded and can be dynamically changed at runtime
  • Solution: intercept the request sent to the service object, add processing logic and decide whether to let it go
  • Roles involved in dynamic proxy classes
  • The public interface of the delegate class (service object) and the proxy class
  • The specific service object that implements the interface
  • The InvocationHandler interface will be called back by the Proxy class. A class that implements the InvocationHandler is needed, and the proxy logic is added to the invoke method.
  • The core class of dynamic proxy Proxy
//接口
public interface Subject {
    
    
    void goshopping();
}

//委托类
public class RealSubject implements Subject{
    
    
    public RealSubject() {
    
    
    }

    @Override
    public void goshopping() {
    
    
        System.out.print("Realgoshopping");
    }
}

//代理类

*基于JDK的动态代理有两个类要记住,Proxy和InvocationHandler( 接口)蔡渣男想找个代理对象代替他白嫖,首先要把自己这个对象托付给一个类,这个类要实现InvocationHandler接口。

这个类实现了这个接口,重写invoke方法对蔡渣男的白嫖方法进行扩展
public class ProxyMan implements InvocationHandler {
    
    
    Subject target;

    public ProxyMan(Subject target) {
    
    
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        System.out.print("开始代理");
        Object result = method.invoke(target, args);//invoke方法是利用反射调用实际的方法
        return result;
    }

    public static void main(String[] args) {
    
    
        Subject realSubject = new RealSubject();
        InvocationHandler proxyMan = new ProxyMan(realSubject);
        Subject realSubjectProxy = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
                new Class<?>[]{
    
    Subject.class}, proxyMan);
        realSubjectProxy.goshopping();//参数分别是 代理类的加载器 被代理的接口 代理类实例 原理是通过反射调用这个方法

    }
}
  1. CgLib dynamic proxy: inheritance

If the proxy class does not implement the interface, CGLIB should be used. CGLIB is a method of proxying the object through inheritance and constructing the subclass of the proxy object. The subclass inherits all the methods of the parent class , which can be passed in the subclass Overload the parent class method to enhance the function.

Need to import Cgilb package

import gdut.iot.softdev.rtti.proxy.cglibproxy.CglibMethodInterceptor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
//父类,委托类 想要对这个类增强,可以构建一个子类来实现
public class Dog {
    
    
    public void call() {
    
    
        System.out.print("www");
    }
}

//拦截类要实现MethodInterceptor接口,在intercept方法中扩展代理对象,注意jdk是对象操作,而cglib是类操作
public class CgLibInterceptor extends CglibMethodInterceptor {
    
    

    @Override
    public Object CglibProxyGeneratory(Class target) {
    
    
        //这里有用到一个类叫Enhancer,通过这个类可以设置委托类为父类,此类为子类
        Enhancer enhancer = new Enhancer();
        //把被代理类设置为父类
        enhancer.setSuperclass(target);
        enhancer.setCallback(this);
        //生成一个继承target类的代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    
    
        System.out.print("k开始代理");
        //对这个类来说,执行原本的方法就是执行他父类的方法,所以用invokeSuper 是方法的调用 不是进行反射 
        Object result = proxy.invokeSuper(obj,args);
        return result;
    }

    public static void main(String[] args) {
    
    
        CgLibInterceptor cgLibInterceptor = new CgLibInterceptor();
        //传入被代理类。
        Dog dogProxy = (Dog) cgLibInterceptor.CglibProxyGeneratory(Dog.class);
        dogProxy.call();
    }

1. The specific implementation principle of JDK dynamic proxy:

Create your own invocation handler by implementing the InvocationHandler interface;

Create a dynamic proxy by specifying a ClassLoader object and a set of interfaces for the Proxy class;

Obtain the constructor of the dynamic proxy class through the reflection mechanism, and its only parameter type is the type of the calling processor interface;

Create a dynamic proxy class instance through the constructor, call the processor object as a parameter when constructing;

2. CGLib dynamic agent:

Use the ASM open source package to load the class file of the proxy object class, and process it by modifying its bytecode to generate subclasses.

3. Comparison of the two:

JDK dynamic proxy is interface-oriented.

CGLib dynamic proxy is implemented through the underlying inheritance of the bytecode to the proxy class, so if the proxy class is modified by the final keyword, it will fail

Guess you like

Origin blog.csdn.net/weixin_45401129/article/details/114629178