Design patterns learning summary (XII) - proxy mode

definition

Proxy mode is to give an object to provide a proxy by the proxy object control references to the original object. In proxy mode, the "third party" proxy primarily play an intermediary role, it connects the client and the target audience.

Character

  • Subject: abstract role. Common interface declaration of a real object and proxy object.

  • Proxy: Proxy role. Proxy object and real object implement the same interface, so it can be able to proxy the real object at any time. Internal agent roles have included a reference to the real object, so she can manipulate real objects, but can also attach other operations, equivalent to the real object encapsulation.

  • RealSubject: true role. It represents a real object, is our ultimate target to reference

Advantages and disadvantages

advantage

  • Proxy mode to coordinate the caller and the caller, the coupling degree is reduced to some extent.

  • Proxy object can play the role of intermediary between the client and the target audience, and this has played a role in the protection of the target object

Shortcoming

  • Since between the client and the real theme of increasing the proxy object, so some type of proxy mode may result in slower processing speed requests.
  • Implementing a proxy mode requires additional work to achieve some agency model is very complex.

Examples

Static agents

UserDao Interface:

public interface IUserDao {
    void save();
}

UserDao achieve:

public class UserDao implements IUserDao {
    @Override
    public void save() {
        System.out.println("保存用户信息");
    }
}

UserDao Agent:

public class UserDaoProxy implements IUserDao {

    private IUserDao iUserDao;

    public UserDaoProxy(IUserDao iUserDao){
        this.iUserDao = iUserDao;
    }
    @Override
    public void save() {
        System.out.println("调用方法前处理");
        iUserDao.save();
        System.out.println("调用方法后处理");
    }
}

transfer:

public class Test {
    public static void main(String[] args) {
        UserDaoProxy userDaoProxy = new UserDaoProxy(new UserDao());
        userDaoProxy.save();
    }
}

Console output:

调用方法前处理
保存用户信息
调用方法后处理

advantage:

可以做到在不修改目标对象的功能前提下,对目标功能扩展.

Disadvantages:

因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

Dynamic Proxy

Dynamic Proxy Features

  • Proxy object, do not need to implement the interface
  • Proxy generation object, using the JDK API, build dynamic proxy object in memory (we need to create a proxy to specify the type of object / target object implements the interface)
  • Dynamic agent also known as: JDK agent, interface agent

Dynamic proxy factory:

public class ProxyFactory {


    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * 生成代理对象
     * 注意 Proxy.newProxyInstance() 方法接受三个参数:
     *      ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
     *      Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
     *      InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法
     * @return
     */
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 执行目标对象方法
                        Object returnValue = method.invoke(target, args);
                        return returnValue;
                    }
                }
        );
    }
}

transfer:

public static void main(String[] args) {
    // 目标对象
    IUserDao target = new UserDao();
    // 【原始的类型 class cn.itcast.b_dynamic.UserDao】
    System.out.println(target.getClass());

    // 给目标对象,创建代理对象
    IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
    // class $Proxy0   内存中动态生成的代理对象
    System.out.println(proxy.getClass());
    // 执行方法
    proxy.save();
}

Console output:

class com.marklogzhu.designpatterns.structure.proxy.dynamic.UserDao
class com.sun.proxy.$Proxy0
保存用户信息

Cglib agent

Cglib agent, also known as sub-class of agents, it is to build a subclass object in memory to achieve function expansion of the target object.

  • JDK dynamic proxy there is a limit, that is, the use of dynamic proxy objects must implement one or more interfaces, if you want the agent class does not implement the interface, you can use Cglib achieved.

  • Cglib is a powerful, high-performance code generator package, it can extend and run java classes implement java interface, which is widely used in many AOP framework, such as Spring AOP and synaop, provide them interception process (blocking)

  • Cglib underlying packet is frame ASM bytecode processing by using a small block to convert byte code and generate a new class. Discouraged ASM directly, because it requires you have an internal structure comprising the JVM class file format and instruction set is very familiar with.

Cglib subclass proxy implementation:

  • 1. The need to introduce cglib jar file, but the Spring core package has been included in Cglib function, so the direct introduction of pring-core-3.2.5.jar can be.

  • 2. After the introduction of the function package, you can dynamically build the subclass in memory

  • 3. Acting classes can not be final, otherwise an error

  • 4. If the target object is final / static, then it will not be intercepted, that method does not perform additional business audience.

Modify the proxy factory class:

public class ProxyFactory implements MethodInterceptor {

    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 创建代理对象
    public Object getProxyInstance() {
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();

    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        //执行目标对象的方法
        Object returnValue = method.invoke(target, args);
        return returnValue;
    }
}

transfer:

public static void main(String[] args) {
    //目标对象
    UserDao target = new UserDao();
    //代理对象
    UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();
    //执行代理对象的方法
    proxy.save();
}

Console output:

保存用户信息

CGLIBDynamic proxy objects created than JDhigher performance dynamic proxy objects created K, but the CGLIBtime it takes to create a proxy object than JDKmuch more. There is no need to create frequent target for a single case, because the object with CGLIBthe right, and vice versa using a JDKway to be more appropriate. And because CGLibas is the use method to dynamically create subclasses for the finalmodified method can not be proxy.

Guess you like

Origin www.cnblogs.com/markLogZhu/p/11582601.html