nonsense

Today, when I was learning Spring, the teacher mentioned proxy mode when talking about AOP, which made me feel a little strange, so I went to learn Java proxy mode first. I don’t know how to learn it. After learning it, I felt that I could understand it thoroughly and got the function of reflection that I had learned before (a lot of knowledge is like this when LEARNING. Maybe the first learning is just swallowed, but the real understanding may be later when learning other knowledge to use, that is why we need to do a project to synthesize the knowledge.) So without saying a word, let’s enter the agency mode of learning.

Introduction to proxy Mode

concept

Proxy is a design pattern that provides additional access to target objects. That is, the target object can be accessed through a proxy object. The advantage of this approach is that additional functional operations can be enhanced based on the implementation of the target object, that is, the function of the target object can be extended. The proxy object is usually referred to as the proxy, and the target object is referred to as the proxied, as we will do later.

Actual chestnuts

We can imagine a scene: when we buy a second-hand house, we may not directly contact the house seller and give money to the house seller, but through a middleman, (I love my Family) such an agency to buy, but in fact we give money to the seller. This is what the proxy model does in abstraction, through the proxy object (I love my family) to access the target object (real seller)

benefits

So what’s the advantage of that? I can also visit the seller directly? This is where AOP comes in (Spring content, slicing oriented), separating our basic business logic from the rest of our processing, and reducing the coupling of our code. At the same time, it is also able to add new functions on the basis of basic functions without changing the source code.

Classification of proxy patterns

Static proxy

Static proxy, as the name implies, is static code, which we have determined at compile time, which can implement our proxy pattern, but lose the flexibility of the code, which cannot meet our dynamic programming needs. Let’s look at the code.

Steps to define the static proxy schema

Create a proxy interface, which is the most basic function that the proxy needs to implement.

interface Object1{
    void action();
}
Copy the code

Create a proxied class to implement the proxied interface and override the methods in the interface.

// Class ObjectImpl implements Object1{@override public void action() { System. The out. Println (" = = = = = = = = = = = is the proxy class starts to be enforced = = = = = = = = = = = = "); System. The out. Println (" = = = = = = = = = = = = = = specific operation = = = = = = = = = = = = = = = = = = "); System. The out. Println (" = = = = = = = = = = = = = = = = = = = be proxy class has been completed the = = = = = = = = = = = = = "); }}Copy the code

3, create a corresponding proxy class, also implement proxy interface, rewrite the method in the interface, define an Object class in the class, used to obtain the Object of the proxy class, and then execute the proxy Object method + its own other function method…

// Class ProxyObject implements Object1{Object1 obj; Public ProxyObject() {system.out.println (" proxy class created successfully "); obj = new ObjectImpl(); } @override public void action() {system.out.println (" the proxy class started executing "); obj.action(); }}Copy the code



In fact, we also found a problem, that is, the code is very inflexible, we need to decide before compiling which classes need to use proxy mode and write corresponding proxy classes for them, which is too much trouble! This is where a dynamic proxy based on reflection comes in!

Dynamic proxy

As mentioned above, dynamic proxy is based on Java reflection principle, so how to use? In fact, we have simplified the one-to-one relationship between the proxied class and the proxied class to the many-to-one relationship between the proxied class and the proxied class. We only need to create a dynamic proxy class, implement the InvocationHandler interface, and then dynamically obtain the proxied object through the incoming, and dynamically execute the proxied object method. This sounds a bit convoluted, so let’s look at the code:

Steps to define the dynamic proxy pattern

1. Create proxy interface, which is the most basic function that the proxy needs to implement (here two different proxies are defined to reflect the function of dynamic proxy)

Interface Subject{void action(); } // interface ClothFactory{void test(); }Copy the code

Create the proxied class, implement the proxy interface, rewrite the method in the interface.

// class RealSubject implements Subject{@override public void action() {system.out.println (" !!!!!!!") ); } // Class NikeclothFactory implements ClothFactory{@override public void test() { System.out.println("Nike factory is processing clothes.........." ); }}Copy the code

Create a dynamic proxy class

class MyInvocationHandler implements InvocationHandler{ Object obj; Public Object blind(Object obj){this.obj = obj; public Object blind(Object obj){this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),this); } // When a call to the overridden method is made through an object of the proxy class, @override Public Object invoke(Object proxy, Method Method, Object[] args) throws Throwable {// Method The return value of the method is returnVal Object returnVal = method.invoke(obj,args); return returnVal; }}Copy the code

The code is explained because this is the key to dynamic proxies; There are several steps in defining a dynamic proxy class: 1. Define a declaration of the object of the proxy class that implements the interface, and then use it to receive the object of the proxy class. 2. Define a Blind method that instantiates the propped object and returns a propped object via reflection. Using the static method proxy. newProxyInstance, we pass in three values: First of all, the class loader of the proxy object and the class loader of the proxy object are the same, plus the interface of the called object, naturally can get the proxy object through reflection. 3. When implementing the InvocationHandler interface, we are asked to implement an Invoke method, which is also the core. When a call is made to the overridden method (a method defined in the interface) via an object of the proxy class, it is automatically converted into a call to invoke. Let’s look at the next two parameters to Invoke, Method and args, and see if they look familiar! Reflection is used to call a method on an Object of the propped class, returning an Object type as the return value holder.

4. Main function call test

Public class DongTai {public static void main(String[] args) {RealSubject real = new RealSubject(); MyInvocationHandler = new MyInvocationHandler(); MyInvocationHandler = new MyInvocationHandler(); / / 3, call blind method, dynamic returns a based on the implementation of the interface of the incoming object of real proxy class object Subject Subject = (Subject) myInvocationHandler. Blind (real); // Sub is the object of the proxy class subject.action(); Example 2: NikeclothFactory Nike = new NikeclothFactory(); ClothFactory factory = (ClothFactory) myInvocationHandler.blind(nike); factory.test(); }}Copy the code

Cglib agent

The acting static and dynamic proxy mode are the target object is to achieve the goal of an interface object, but sometimes the target object is only a single object, did not implement any interface, you can use this time to target a subclass class implements agent, this method is called: additional agent, this section I will come again later.

Write in the last

So far, the agent mode is basically finished, if you have any questions can talk to me privately, but I believe that after learning reflection you can understand the mystery!!