I walk very slowly, but I never walk backwards 
Copy the code

Design pattern – Proxy pattern

Become as

Hello, everyone, I am silent, in this class, we will talk about the design mode of the agent mode, the agent mode I believe we have been more familiar with, then we directly look at the basic introduction of the agent mode

Basic introduction

Proxy Pattern is introduced as follows:

Proxy mode: Provide a proxy for an object to control access to that object, i.e. access to the target object through the proxy object. The advantage of this is to enhance the implementation of the target object, that is, to extend the functionality of the target object

The principle of proxy mode is to use a proxy object to wrap the target object, and then replace the target object with the proxy object. The proxy class and the proided class have the same parent class or implement the same interface, so that any operation on the target object can be replaced by the proxy class. The corresponding business logic can be added inside the proxy class before and after the implementation details of the target object are invoked

The principle of class diagram

Originally we used the client to call the target object directly

Now we wrap the target object with a proxy object, and the client operates on the target object by calling the proxy class

Pattern classification

There are two main forms of proxy mode, static proxy and dynamic proxy. Dynamic proxy is divided into JDK proxy and Cglib proxy. The following are detailed analysis and case demonstration of each type

Static agent

When static proxies are used, interfaces or parent classes need to be defined. The proxied object (that is, the target object) implements the same interface or inherits the same parent class with the proxied object. The following examples are used to demonstrate this

Case presentation

Requirements: Suppose we have a teacher who has something to do today and can only teach remotely. We find another teacher to help us complete the teaching task

The class diagram analysis

Code demo
Public interface ITeacher {// teach public void teach(); } public class implements ITeacher {@override public void teach() { System.out.println(" Target lecturer is teaching "); Public class ProxyTeacher implements ITeacher {private ITeacher implements ITeacher; public ProxyTeacher(ITeacher iTeacher) { this.iTeacher = iTeacher; } @override public void teach() {system.out.println (); iTeacher.teach(); System.out.println(" Proxy lecturer closes the video conference function and the lecture ends "); Public class Client {public static void main(String[] args) {TargetTeacher TargetTeacher = new TargetTeacher(); New ProxyTeacher(targetTeacher).teach(); }}Copy the code

In fact, we can see from the case that the so-called static, that is, the relationship between the proxy class and the proxy class is determined before running, and the bytecode file of the proxy class already exists before running the program


The business logic can be extended to the target function by proxy object without modifying the target function


In fact, this is not conducive to program extension, because the proxy object needs to implement the same interface as the target object, that a proxy class can only serve one or a set of interfaces, so the development of the program may produce a large number of proxy classes once the interface adds methods, the target object and the proxy object have to maintain

Dynamic proxy – JDK proxy

Dynamic proxy refers to the method that the client calls the target object through the proxy class. It is the proxy object that dynamically creates the target class according to the needs when the program runs

The proxy object does not need to implement the interface, but the target object needs to implement the interface, otherwise dynamic proxy cannot be used. The relationship between the proxy class and the proxied class is determined when the program runs


To implement dynamic proxies, consider the following two issues:

Question 1: How to dynamically create proxy classes and their objects based on the proxy classes loaded in memory?

Proxy class generation, is the use of JDK API, dynamically build proxy objects in memory

Proxy class package: java.lang.reflect.proxy

The JDK implementation proxy only needs to use the newProxyInstance method, but this method takes three parameters, as explained in detail in the case

How to dynamically call a method of the same name of the proxied class when calling a method from an object of the proxied class?

We’ll answer that question in the course of the code demo

Case presentation

Take the case that started with static proxy and improve it to dynamic proxy mode

The class diagram analysis

Code demo
Public interface ITeacher {// teach public void teach(); } public class implements ITeacher {@override public void teach() { System.out.println(" Target lecturer is teaching "); Public class ProxyFactory {// Maintain a target Object private Object target; Public ProxyFactory(Object target) {this.target = target; } public Object getProxyInstance() {// Parameter Description //ClassLoader loader: specifies the Class loader used by the target Object. The method for obtaining the Class loader is fixed. >[] interfaces: the type of the interface implemented by the target object, using generic methods to confirm the type. Event handling, when executing a method on the target object, Return proxy.newProxyInstance (target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method Method, Object[] args) throws Throwable {system.out.println ("JDK proxy start "); Call getProxyInstance (); // Invoke (); // Invoke (); Add the corresponding business logic Object returnVal = method.invoke(target, args); System.out.println("JDK proxy submission "); return returnVal; }}); }} public class Client {public static void main(String[] args) {ITeacher targetTeacher = new targetTeacher (); ITeacher proxyInstance = (ITeacher) new ProxyFactory(targetTeacher).getProxyInstance(); //class com.sun.proxy.$Proxy0 = system.out.println (proxyinstance.getClass ()); // Call the target object's method proxyinstance.teach () via the proxy object; }}Copy the code

Dynamic proxy – Cglib proxy

Antecedents feed

Both static proxies and JDK proxies require the target object to implement an interface, but sometimes the target object is a single object that does not implement any interface. In such cases, you can use a subclass of the target object to implement the proxy, which is called the Cglib proxy

Additional agent

The Cglib proxy, also known as a subclass proxy, builds a subclass object in memory to extend the functionality of the target object

Cglib is a powerful high-performance code generation package that can extend Java classes and implement Java interfaces at runtime. The underlying Cglib package uses the bytecode processing framework ASM to convert bytecode and generate new classes. It is widely used by many AOP frameworks. For example, Spring AOP, to implement method interception, uses the Cglib proxy, and the target object does not need to implement any interface

Of course, cglib-related dependencies need to be introduced before use

<! --Cglib--> <! -- https://mvnrepository.com/artifact/cglib/cglib --> <dependency> <groupId>cglib</groupId> < artifactId > additional < / artifactId > < version > 2.2.2 < / version > < / dependency >Copy the code
Case presentation

To improve the Cglib proxy pattern from an initial case done using a static proxy

The class diagram analysis

Code demo
Public class TargetTeacher {public void teach() {system.out.println (" TargetTeacher is teaching "); Public class ProxyFactory implements MethodInterceptor {// Maintain a target Object private Object target; public ProxyFactory(Object target) { this.target = target; Public Object getProxyInstance(){// Create a tool class Enhancer Enhancer = new Enhancer(); // Set the parent class to enhancer.setsuperclass (target.getClass()); // Set the callback function enhancer.setcallback (this); Return enhancer.create(); } // Override this method, @override public Object Intercept (Object o, Method Method, Object[] objects, MethodProxy MethodProxy) throws Throwable {system.out.println ("Cglib proxy mode starts =-="); Object returnVal = method.invoke(target, objects); System.out.println("Cglib proxy mode end =-="); return returnVal; Public class Client {public static void main(String[] args) {TargetTeacher TargetTeacher = new TargetTeacher(); // Get the proxy object and pass the target object to TargetTeacher proxyInstance = (TargetTeacher)new ProxyFactory(TargetTeacher).getProxyInstance(); proxyInstance.teach(); }}Copy the code

Several common variations of the proxy pattern

Firewall agent

The Intranet penetrates the firewall through proxies to realize access to the public network. In fact, the idea is the same, but it is applied to the firewall

The caching proxy

For example, when requesting resources such as image files, the system first obtains the resources from the cache proxy. If the resources are obtained, the system ok. If the resources are not obtained, the system obtains the resources from the public network or the database, and then puts them into the cache

Remote agent

A local representation of a remote object through which the remote object can be called as a local object. The remote proxy communicates information to the real remote object over the network

Synchronous agent

Mainly used in multi-threaded programming, complete multi-threaded synchronization work

Next day forecast

OK, here, the related content of proxy mode is over. In the next section, we will start the study of template mode. I hope we can stick to it together and really gain something