There are many categories of design patterns in Java, mainly divided into three categories: creation type, structure type and behavior type. The proxy pattern to be introduced in this article belongs to one of the structural design patterns. The following is a detailed explanation of the proxy pattern in Java.
1, Agent mode
What is the agent model?
If you want to buy a ticket, you don't have to go to the station to buy it; Instead, you can go to a consignment point to sell tickets at the station. This is a simple agency model!
- It mainly solves the problems caused by directly accessing objects. For example, the object to be accessed is on a remote machine. In an object-oriented system, direct access to some objects will bring a lot of trouble to users or system structure for some reasons (such as high object creation cost, or some operations need security control, or need out of process access). We can add an access layer to this object when accessing this object.
- Summary: we access instance objects through proxy objects, which is flexible and can add some additional operations
2, Static proxy
As the name suggests, it is static and constructed by programmers. The program interface, proxy class and proxy class have been written before compilation! It has been generated before the program runs!
A simple example:
Design common interface Person:
public interface Person { public void handinWork(); }
Student:
public class Student implements Person { private String name; public Student(String name) { this.name=name; } public void setName(String name) { this.name = name; } public void handinWork() { System.out.println(name+"Submit job"); } }
Proxy class StudentProxy:
public class StudentProxy implements Person { //Agent who Student student; //Prevent duplicate names and ensure that only the Student object is represented public StudentProxy(Student student) { if(student.getClass()==Student.class){ this.student = (Student) student; } } public void handinWork() { //When handing in the homework, the agent (monitor) wants to do something instead of the students··· System.out.println("The teacher copied this assignment"); student.handinWork(); } }
Test:
public class StaticProxy { public static void main(String[] args) { //Create two objects, proxy and proxied Student student = new Student("Zhang San"); StudentProxy monitor = new StudentProxy(student); //Agent class to hand in homework!!!!! monitor.handinWork(); } }
It can be found that the essence of the program is that students hand in their homework, but it is realized through an intermediate layer monitor. Then, the agent layer can add some other operation functions before or after submitting their homework!
3, Dynamic agent
Static agent is generated before the program runs. It is obvious that dynamic agent is to add agent layer during the program runs to achieve the effect. Dynamic generation of agent class!
- Two classes need to be understood: Proxy proxy and InvocationHandler
- Proxy: proxy class, generated dynamically when used
- InvocationHandler: it mainly executes the methods that need proxy, and uses invoke to execute
For example: it is easy to understand. In the above example, we transform it into a dynamic one!
The first step is to create a class to implement the InvocationHandler interface, and use it to build the proxy class and proxy method:
public class ProxyInvocation implements InvocationHandler { //Proxied interface, real object private Person person; //Generated proxy class public void setPerson(Person person) { this.person = person; } //Create a Proxy object through the newProxyInstance method of the Proxy class. Let's look at the parameters in the method // *The first parameter: people getClass(). Getclassloader (), use the classloader object of the handler object to load our proxy object // *The second parameter: people getClass(). Getinterfaces(), where the interface provided for the proxy class is the interface implemented by the real object, so that the proxy object can call all methods in the interface like the real object // *The third parameter: handler. We associate the proxy object with the InvocationHandler object above public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),person.getClass().getInterfaces(),this); } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(person, args); return result; } }
Referring to the static Proxy, we need a Proxy object, but the Proxy object in the static Proxy is created manually, so in the dynamic Proxy, we use the newProxyInstance method of the Proxy class of jdk to dynamically generate a Proxy class, which can be changed dynamically according to the parameters we pass,
Test:
//Real role student Student student = new Student("Zhang San"); //Get the inherited class of InvocationHandler ProxyInvocation pih = new ProxyInvocation(); //Get the interface of the agent pih.setPerson(student); //The proxy class is generated dynamically Person proxy = (Person) pih.getProxy(); //Proxy class execution method proxy.handinWork();
Improved to tool class: all the interfaces obtained are replaced by parameters;
private Object target; //Generated proxy class public void setPerson(Object target) { this.target= target; } //Create a Proxy object through the newProxyInstance method of the Proxy class. Let's look at the parameters in the method // *The first parameter: people getClass(). Getclassloader (), use the classloader object of the handler object to load our proxy object // *The second parameter: people getClass(). Getinterfaces(), where the interface provided for the proxy class is the interface implemented by the real object, so that the proxy object can call all methods in the interface like the real object // *The third parameter: handler. We associate the proxy object with the InvocationHandler object above public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(person, args); return result; }
Just change the interface type and parameters! The use of proxy mode on Spring will be added later,
4, Summary
If you don't type the code again, you will never understand it. You can't learn it if you learn it again instead of completely understanding it! Check more information, understand more code, and spend more time to understand! Old fellow. Learn programming with a problem-solving attitude, not for a well paid job.