Head First Design Patterns-- proxy mode


Proxy mode refers to the use of a proxy class is now to conduct another proxy the target class, for example, when we generally rent an apartment, and the landlord does not negotiate directly, and operates by real estate agents, because their hands may have many listings for landlords, they can communicate directly with the housing agency. Similar examples are numerous, and such Hollywood stars, have their own economy, of course, here refers to the strong economic man is not a treasure, a joke, people in charge of their economic star of economic activity, in this case is the agent mode!

Proxy mode is divided into: static proxy mode, dynamic generation model (jdk dynamic proxy), cglib dynamic proxy mode three kinds!

A static proxy mode:

Here we will use an example to illustrate the principle of renting,

  • FIG class as follows:

Here Insert Picture Description
Probably explain:
there is an interface Host, which has Rent rental method, and then let HostImpl landlord to implement Host method, this is the target class, really want to rent the landlord of the house, proxy as an intermediary target, it implements Host method, then HostImpl polymerized within the class object, call HostImpl, so that the landlord can help to rent house below the specific code implementation point of view:

  • Code
public interface Host {

    void Rent();

}

public class HostImpl implements Host {
    @Override
    public void Rent() {
        System.out.println("房东要租房子");
    }
}

public class proxy implements Host{

    //聚合HostImpl
    HostImpl host;

    public proxy(HostImpl host) {
        this.host = host;
    }

    @Override
    public void Rent() {
        System.out.println("代理开始工作");
        //调用HostImpl中的Rent方法
        host.Rent();
    }
}
public class Client {
    public static void main(String[] args) {
        proxy proxy = new proxy(new HostImpl());
        proxy.Rent();
    }
}
  • Operating results
    Here Insert Picture Description
    static proxy:
    Advantages: In function without modification of the target object, a proxy object through the target extensions
    disadvantages:
    (1) because the proxy object needs to implement the same interface as the target object, all have a lot proxy class
    (2) Once the interface method for increasing the target object and proxy object must be maintained

Second, the dynamic generation model (JDK dynamic proxies):

Basic introduction:
1) proxy object does not need to implement the interface, but the target object to implement the interface, or can not use dynamic proxies
2) generates proxy object is to use the JDK API, build dynamic proxy object in memory
3), also known as dynamic agents : JDK agent, interface agent

  • FIG class as follows:
    Here Insert Picture Description
    getProxyInstacne ():
    1. The incoming object (HostImpl), the target object
    2 by using reflection, returns a proxy object
    3 and then through the proxy object, the target object method invocation
  • Code
public interface Host {

    void Rent();

}

public class HostImpl implements Host {
    @Override
    public void Rent() {
        System.out.println("房东要租房子");
    }
}

public class MyInvocationHadler implements InvocationHandler {

    private Object target;

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

    //执行目标方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK代理");
        //利用反射机制调用目标对象的方法
        Object returnVal = method.invoke(target, args);
        System.out.println("JDK代理提交");
        return returnVal;
    }
}

public class ProxyFactory {

    private Object target;

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

    //给目标对象,生成一个代理对象
    public Object getProxyInstance(){

        /**
         * public static Object newProxyInstance(ClassLoader loader,
         *                                 Class<?>[] interfaces,
         *                                 InvocationHandler h)
         */
        //1.ClassLoader loader:指定当前目标对象使用的类加载器
        //2.Class<?>[] interfaces:目标对象实现的接口类型,使用泛型确认类型
        //3.InvocationHandler h):事件处理,执行目标对象的方法,会触发事件处理器方法
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new MyInvocationHadler(target));
    }
}
  • Test Results
    Here Insert Picture Description
  • Debug can be observed through the
    Here Insert Picture Description
  • 类图 office shows
    Here Insert Picture Description

Three, Cglib dynamic proxy mode:

basic introduction:

1) static agents and JDK dynamic proxies are required to achieve the target object is an interface, but sometimes the target object is just a single object, and does not implement any interfaces, this time you can make the audience sub-categories to achieve a proxy, which is Cglib proxy.
2) Cglib agent, also known as sub-agent class, it is to build a sub-class object in memory in order to achieve the target object extensions, sometimes attributed to the Cglib dynamic proxy agent.
3) Cglib agent is a powerful, high-performance code generation package, which can extend and implement java class java interface, which is widely used in many AOP frame during operation, for example: Spring AOP achieve intercept method
4) in AOP how to select a proxy mode programming:
4.1) target needs to implement the interface , use JDK agent
4.2) the target object does not need to implement the interface , use Cglib agent
underlayer. 5) Cglib packet by using the process frame ASM, bytecode conversion words section of code and generate a new class

  • jar package Cglib use:

22jar-cglib
asmjar
commonsjar
asm-treejar

No small jar package can be downloaded edible partners:
link: https: //pan.baidu.com/s/16XEWkAGapxnmT4Li4ocKDA
extraction code: sa4k

  • FIG following class
    Here Insert Picture Description
  • Code
public class HostImpl {

    public void Rent(){
        System.out.println("房东要租房子,cglib方式");
    }
}
public class ProxyFactory implements MethodInterceptor {
    //给一个目标对象
    private Object target;

    //构造器,用于初始化被代理的对象
    public ProxyFactory(Object target) {
        this.target = target;
    }
    //返回一个代理对象,是target对象的代理对象
    public Object getProxyInstance(){
        //1.创建一个工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(target.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类对象,即代理对象
        return enhancer.create();
    }

    //重写intercept方法,会调用目标对象的方法
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib代理模式*******开始");
        Object returnVale = method.invoke(target, args);
        System.out.println("cglib代理模式*******提交");
        return returnVale;
    }
}

public class Client {
    public static void main(String[] args) {
        //目标对象
        HostImpl target = new HostImpl();
        //获得到代理对象,并且将目标对象传递给代理对象
        HostImpl proxyFactory = (HostImpl)new ProxyFactory(target).getProxyInstance();

        //执行代理对象的方法,触发intercept方法,从而实现对目标对象调用
        proxyFactory.Rent();
    }
}
  • operation result
    Here Insert Picture Description
  • Debug can be observed through the
    Here Insert Picture Description
  • The class diagram in the form of
    Here Insert Picture Description
    summary:
    When cglib generate dynamic proxy, target audience and ProxyFactory do not need to implement the interface!
Published 47 original articles · won praise 34 · views 8860

Guess you like

Origin blog.csdn.net/weixin_42893085/article/details/105383364