The Spring5 framework provides an in-depth understanding of the use of the beginner’s proxy pattern
“This is the 25th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
About the author
- The authors introduce
🍓 Blog home Page: author home page 🍓 Introduction: High-quality creator in the JAVA field 🥇, a junior student 🎓, participated in various provincial and national competitions during school, and won a series of honors 🍓, Ali Cloud expert blogger, 51CTO expert blogger, follow me: Pay attention to my learning materials, document download all have, regularly update the article every day, inspirational to do a JAVA senior program ape 👨💻
12. Proxy mode
Experience design patterns for the first time, maybe in the last AOP in some places you may not understand, let’s first explain the idea of AOP design and the underlying principles. Understanding aop later will be relatively easy.
Why learn the proxy pattern, because the underlying mechanism of AOP is dynamic proxies!
Proxy mode:
- Static agent
- A dynamic proxy
UML diagrams
12.1 Static Proxy
Static proxy role analysis
ISubject(Abstract Role) : Implemented using interfaces and abstract classes.
RealSubject: The role being proxied.
Proxy: Proxy for a real role. After proxy for a real role, there are ancillary operations.
Client: Uses the agent to select its own requirements.
Code implementation
Isubject. Java Abstract role
package com.spring.demo01;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo01
* @ClassName: ISubject
* @Author: Shengrui Zhang *@Date: 2022/2/12 all *@Version: 1.0 * /
// Abstract role: agent
public interface ISubject {
public void shop(a);
}
Copy the code
Merchant. Java Real role
package com.spring.demo01;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo01
* @ClassName: Merchant
* @Author: Shengrui Zhang *@DateHe: 2022/2/12 *@Version: 1.0 * /
// The merchant's real role
public class Merchant implements ISubject{
@Override
public void shop(a) {
System.out.println("Merchant will send the goods to the agent!!"); }}Copy the code
Proxy. Java Proxy role
package com.spring.demo01;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo01
* @ClassName: Proxy
* @Author: Shengrui Zhang *@Date: 2022/2/12 14:21
* @Version: 1.0 * /
// Taobao agent agent role
public class Proxy implements ISubject{
private Merchant merchant;
public Proxy(Merchant merchant) {
this.merchant = merchant;
}
// The goods after the agent
@Override
public void shop(a) {
merchant.shop();
buy();
Insurance_service();
}
// The customer buys the goods
public void buy(a){
System.out.println("User buys goods");
}
// The broker earns the difference
public void Insurance_service(a){
System.out.println("The agent provides insurance and other services for the goods."); }}Copy the code
Client. Java Client
package com.spring.demo01;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo01
* @ClassName: Client
* @Author: Shengrui Zhang *@Date: 2022/2/12 * to them@Version: 1.0 * /
// Customer class, general customers will go to the agent to buy goods!
public class Client {
public static void main(String[] args) {
// Customers buy goods
Merchant merchant = new Merchant();
// The merchant looks for an agent
Proxy proxy = new Proxy(merchant);
// The client goes directly to the agentproxy.shop(); }}Copy the code
Analysis of the
In this process, the customer direct contact is intermediary agents, just as in real life, we cannot directly in contact with the merchants, but still able to buy through agent merchant goods, this is the so-called agency model, program is derived from life, so to learn programming, generally more abstract events in the way of looking at life.
summary
- In the future, if you write your own interface and you want to get the instantiation object of the interface, the first reaction is to write the factory class
- The simple factory differs from the factory method pattern in that the behavior of the generated product is encapsulated in a method, instantiated according to the type of parameter, and there is no abstract interface. In the latter, abstract factories are added to create different products by implementing different factory methods, one method usually corresponds to one product. This method has higher expansibility than the former, and fully conforms to the open-closed principle and dependency inversion principle when demand increases
benefits
- It can make our real role more pure and not focus on public things.
- The common business is completed by the agent. The division of business is realized.
- Common services become more centralized and convenient when they are extended.
disadvantages
- With more classes and more proxy classes, the amount of work becomes larger and the development efficiency is reduced.
We want the benefits of static proxies without the disadvantages, so here we have dynamic proxies!
12.2 Understanding Static Proxy again
Practice steps:
-
Create an abstract role, such as zha people usually do user business, abstract up is add delete change check!
package com.spring.demo02; / * * *@ProjectName: Spring5study * @Package: com.spring.demo02 * @ClassName: UserService * @Author: Shengrui Zhang *@Date: 2022/2/12 14:42 * @Version: 1.0 * / // Abstract roles: add, delete, change and check services public interface UserService { void add(a); void delete(a); void update(a); void query(a); } Copy the code
-
We need a real object to do this
package com.spring.demo02; / * * *@ProjectName: Spring5study * @Package: com.spring.demo02 * @ClassName: UserServiceImpl * @Author: Shengrui Zhang *@Date: 2022/2/12 14:42 * @Version: 1.0 * / public class UserServiceImpl implements UserService{ @Override public void add(a) { System.out.println("Added a user."); } @Override public void delete(a) { System.out.println("Deleted a user"); } @Override public void update(a) { System.out.println("Updated a user"); } @Override public void query(a) { System.out.println("Query a user"); }}Copy the code
-
Demand comes, now we need to add a log function, how to achieve!
- Idea 1: Add code to the implementation class.
- Idea 2: Using proxies is the best way to do this without changing the business.
-
Set up a proxy class to handle logging! The agent role
package com.spring.demo02; / * * *@ProjectName: Spring5study * @Package: com.spring.demo02 * @ClassName: UserServiceProxy * @Author: Shengrui Zhang *@Date: 2022/2/12 for *@Version: 1.0 * / public class UserServiceProxy implements UserService{ private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } public void add(a) { log("add"); userService.add(); } public void delete(a) { log("delete"); userService.delete(); } public void update(a) { log("update"); userService.update(); } public void query(a) { log("query"); userService.query(); } public void log(String msg){ System.out.println("Executed."+msg+"Method"); }}Copy the code
-
Test access class
package com.spring.demo02; / * * *@ProjectName: Spring5study * @Package: com.spring.demo02 * @ClassName: Client * @Author: Shengrui Zhang *@Date: 2022/2/12 when *@Version: 1.0 * / public class Client { public static void main(String[] args) { // Real business UserServiceImpl userService = new UserServiceImpl(); / / the proxy class UserServiceProxy proxy = new UserServiceProxy(); // Use proxy classes to implement logging!proxy.setUserService(userService); proxy.query(); }}Copy the code
OK, now we should have no problem with the proxy model, the key point is that we need to understand the idea;
The core idea in AOP is that we have implemented enhancements to the original functionality without changing the original code.
Talk about AOP: Vertical development, horizontal development
12.3 Dynamic Proxy
- The role of a dynamic proxy is the same as that of a static proxy
- The proxy class for dynamic proxy is dynamically generated. The proxy class for static proxy is written in advance.
- Dynamic proxy can be divided into two types: dynamic proxy based on interface and dynamic proxy based on class
- Interface based dynamic proxy —-JDK dynamic proxy
- Class – based dynamic proxy – Cglib
- Now more use is javasist to generate dynamic proxy. Baidu javasist
- Here we use JDK native code to implement, the rest of the reason is the same!
JDK dynamic proxies need to know about two core classes: InvocationHandler and Proxy. Open the JDK help documentation to see
【InvocationHandler 】
/ / parameters
//proxy - the proxy instance that calls the method
//method - The method corresponds to invoking an instance of an interface method on a proxy instance. The declaration class of a method object will be the interface that the method declares, which can be the superinterface of the proxy interface that the proxy class inherits from the method.
//args - Contains an array of objects for method calls that pass the proxy instance's parameter values, or null if the interface method has no parameters. Parameters of primitive types are contained in instances of the appropriate primitive wrapper classes, such as java.lang.Integer or java.lang.Boolean
Object invoke(Object Proxy, method, Object[] args);Copy the code
【Proxy 】
// Generate the proxy class
public Object getProxy(a){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
Copy the code
Code implementation
The abstract and real characters are the same as before!
ISubject.java
package com.spring.demo03;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo03
* @ClassName: ISubject
* @Author: Shengrui Zhang *@Date: 2022/2/12 15:52
* @Version: 1.0 * /
// Abstract role: agent
public interface ISubject {
public void shop(a);
}
Copy the code
Merchant.java
package com.spring.demo03;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo03
* @ClassName: Merchant
* @Author: Shengrui Zhang *@Date: 2022/2/12 when *@Version: 1.0 * /
// The merchant's real role
public class Merchant implements ISubject {
@Override
public void shop(a) {
System.out.println("Merchant will send the goods to the agent!!"); }}Copy the code
ProxyInvocationHandler.java
package com.spring.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo03
* @ClassName: ProxyInvocationHandler
* @Author: Shengrui Zhang *@Date: 2022/2/12 15:57
* @Version: 1.0 * /
public class ProxyInvocationHandler implements InvocationHandler {
private ISubject iSubject;
public void setiSubject(ISubject iSubject) {
this.iSubject = iSubject;
}
// Generate the proxy class, focusing on the second argument, to get the abstract role to proxy! It used to be one role, but now it can represent a class of roles
public Object getProxy(a){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
iSubject.getClass().getInterfaces(),this);
}
// proxy: method: method object of the invocation handler of the proxy class.
// Process method calls on proxy instances and return results
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Core: Essence is realized by reflection!
Object result = method.invoke(iSubject, args);
returnresult; }}Copy the code
Client.java
package com.spring.demo03;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo03
* @ClassName: Client
* @Author: Shengrui Zhang *@Date: 2022/2/12 16:01
* @Version: 1.0 * /
public class Client {
public static void main(String[] args) throws ClassCastException{
// Real characters
Merchant merchant = new Merchant();
// The invocation handler for the proxy instance
ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler();
// Put the real character in!
invocationHandler.setiSubject(merchant);
// Dynamically generate the corresponding proxy class!ISubject proxy = (ISubject) invocationHandler.getProxy(); proxy.shop(); }}Copy the code
Core: a dynamic proxy, general proxy a certain kind of business, a dynamic proxy can proxy multiple classes, proxy is the interface
12.4 Deepen understanding
Use the dynamic proxy implementation to proxy UserService!
Can write a general dynamic proxy implementation of the class! Set all proxy objects to Object!
ProxyInvocationHandler template
package com.spring.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo03
* @ClassName: ProxyInvocationHandler
* @Author: Shengrui Zhang *@Date: 2022/2/12 15:57
* @Version: 1.0 * /
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setiSubject(Object target) {
this.target = target;
}
// Generate the proxy class, focusing on the second argument, to get the abstract role to proxy! It used to be one role, but now it can represent a class of roles
public Object getProxy(a){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
// proxy: method: method object of the invocation handler of the proxy class.
// Process method calls on proxy instances and return results
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
// Core: Essence is realized by reflection!
Object result = method.invoke(target, args);
return result;
}
public void log(String methodName){
System.out.println("Executed."+methodName+"Method"); }}Copy the code
test
package com.spring.demo04;
import com.spring.demo02.UserService;
import com.spring.demo02.UserServiceImpl;
/ * * *@ProjectName: Spring5study
* @Package: com.spring.demo04
* @ClassName: Test
* @Author: Shengrui Zhang *@Date: 2022/2/12 25 *@Version: 1.0 * /
public class Test {
public static void main(String[] args) {
// Real objects
UserServiceImpl userService = new UserServiceImpl();
// The invocation handler for the proxy object
ProxyInvocationHandler pih = new ProxyInvocationHandler();
// Set the object to be proxied
pih.setTarget(userService);
// Dynamically generate proxy classes!UserService proxy = (UserService)pih.getProxy(); proxy.delete(); }}Copy the code
Benefits:
Static proxy has it, static proxy does not have, it also has!
- It can make our real role more pure and not focus on public things.
- The common business is done by the agent, realizing the division of business.
- Common services become more centralized and convenient when they are extended.
- A dynamic proxy, typically for a certain type of service.
- A dynamic proxy can proxy multiple classes, proxy is the interface!
After the language
The original intention of the director to write blog is very simple, I hope everyone in the process of learning less detours, learn more things, to their own help to leave your praise 👍 or pay attention to ➕ are the biggest support for me, your attention and praise to the director every day more power.
If you don’t understand one part of the article, you can reply to me in the comment section. Let’s discuss, learn and progress together!