AOP (Aspect Oriented Programming) does not create or use new technologies, its underlying implementation is based on the proxy pattern. So let’s look at the agency model first.
I. Basic concepts
1.1 define
Proxy pattern, which provides a proxy for an object to control access to that object.
1.2 the role
The proxy pattern, also known as the delegate pattern, generally has the following three roles
- Abstract Topic role: An abstract topic class, which can be an abstract class or an interface, is a common business type definition with no special requirements.
- Specific subject roles: Also known as delegated or deputized roles, are the actual implementer of specific business logic.
- Proxy object roles: Also known as delegate classes, proxy classes. Logic that is responsible for controlling access to and application of a specific topic role and can be pre-processed and post-processed before and after the execution of the business logic of the specific topic role.
From the definition of “specific subject roles” we can make one thing clear: the relationship between the proxy class and the proxy class in the proxy pattern does not mean that the proxy class helps the proxy class to do all the work. Instead, the core work is still done by the proxy class itself. The function of the proxy class is to control the access, application, and other processing before and after the core business logic is performed by the proxy class. The following practices will help us understand better.
Second, the basic implementation of simple proxy pattern
Here we start with a basic implementation of a simple proxy pattern based on the basic concepts. Consider this scenario: stars and agents. Agents help stars negotiate cooperation with the outside world, sign contracts and calculate commissions; Stars perform acts, sing songs, etc. First define an actor.java
package com.leng.proxy;
/ * * *@Classname Actor
* @Date 2020/9/12 23:30
* @Autor lengxuezhang
*/
public interface Actor {
/** * acting */
public void act(a);
/** * sing */
public void sing(a);
}
Copy the code
An artist usually needs to be able to sing and act. We then implement the star class separately, implementing the Actor interface, and passing in the name.
package com.leng.proxy;
/ * * *@Classname Star
* @Date2020/9/12 did *@Autor lengxuezhang
*/
public class Star implements Actor {
private String name;
public Star(String name) {
this.name = name;
}
@Override
public void act(a) {
System.out.println(name + "Acting.");
}
@Override
public void sing(a) {
System.out.println(name + "Singing."); }}Copy the code
Finally realizable broker
package com.leng.proxy;
/ * * *@Classname Agent
* @Date2020/9/12 declare *@Autor lengxuezhang
*/
public class Agent implements Actor {
private Actor actor = null;
// To implement the broker agent star, you need to pass the proxy class object to the proxy class
public Agent(Actor actor) {
this.actor = actor;
}
@Override
public void act(a) {
this.before();
// The actual act() is called by the star, and the agent takes the job, but in the end, the star is the star himself
actor.act();
this.after();
}
@Override
public void sing(a) {
this.before();
actor.sing();
this.after();
}
// Preprocessing method
private void before(a) {
System.out.println("Negotiate the price and sign the contract.");
}
// Post processing method
private void after(a) {
System.out.println("Liquidate performance fees, split stars."); }}Copy the code
The Client calls client.java:
package com.leng;
import com.leng.proxy.Agent;
import com.leng.proxy.Star;
/ * * *@Classname Client
* @Date 2020/9/12 2:40
* @Autor lengxuezhang
*/
public class Client {
public static void main(String[] args) {
Star star = new Star("Andy Lau");
Agent agent = newAgent(star); agent.act(); agent.sing(); }}Copy the code
Running result:
Negotiate a good price, sign a good contract Andy Lau in acting liquidation performance fee, and star money to negotiate a good price, sign a good contract Andy Lau in singing liquidation performance fee, and star moneyCopy the code
Summary:
- The key to the implementation of the proxy pattern is that the proxy class holds the object of the proxy class so that it can perform the business logic that the proxy class itself wants to perform.
- The proxy class can define its own pre – and post-processing methods to execute before and after the business logic of the proxy class.
The above is called an example of the concept based on the broker pattern, but the broker pattern actually has some new features under different scenarios or requirements. Such as the general agent and mandatory agent described next.
Third, the extension of the proxy mode
3.1 General Agent
The star’s work is generally busy, there is no time to have too much communication and contact with the outside world. The director wants to find a star to act, generally can only go to contact his company agent first, is unable to contact the star himself. “The director can only contact the agent, but not the star”, such a model is called “general agency”. In other words, in general proxy mode, the client can only access the proxy class, but not the proxy class. In client.java, we directly new a star object, which is a direct access to the proxied class and cannot be called a common proxy. So how can we implement general proxy. The key is to make the creation of the proscribed class only done by the proscribed class. Change the code as follows: You only need to change the constructor
package com.leng.proxy;
/ * * *@Classname Star
* @Date2020/9/12 did *@Autor lengxuezhang
*/
public class Star implements Actor {
private String name;
public Star(Agent agent, String name) throws Exception {
// You have to be an agent to create a star
if(agent == null) {
throw new Exception("You can't create a star without being an agent.");
} else {
this.name = name; }}@Override
public void act(a) {
System.out.println(name + "Acting.");
}
@Override
public void sing(a) {
System.out.println(name + "Singing."); }}Copy the code
package com.leng.proxy;
/ * * *@Classname Agent
* @Date2020/9/12 declare *@Autor lengxuezhang
*/
public class Agent implements Actor {
private Actor actor = null;
// Tell agent which "star" I need to contact
public Agent(String name) {
try {
this.actor = new Star(this, name);
} catch (Exception e) {
System.out.println("Failed to create agent"); }}@Override
public void act(a) {
this.before();
actor.act();
this.after();
}
@Override
public void sing(a) {
this.before();
actor.sing();
this.after();
}
// Preprocessing method
private void before(a) {
System.out.println("Negotiate the price and sign the contract.");
}
// Post processing method
private void after(a) {
System.out.println("Liquidate performance fees, split stars."); }}Copy the code
When the client class is used, it also needs to be modified so that the client can not access the Star directly
package com.leng;
import com.leng.proxy.Agent;
/ * * *@Classname Client
* @Date 2020/9/12 2:40
* @Autor lengxuezhang
*/
public class Client {
public static void main(String[] args) {
Agent agent = new Agent("Andy Lau"); agent.act(); agent.sing(); }}Copy the code
Running result:
Negotiate a good price, sign a good contract Andy Lau in acting liquidation performance fee, and star money to negotiate a good price, sign a good contract Andy Lau in singing liquidation performance fee, and star moneyCopy the code
You can see that the result of the run has not changed, but it has been implemented that you can only access non-proxy classes in the same way that you can access proxy classes. If the client accesses the proxy class directly, an exception will be thrown. Advantages of the general agent mode:
- The caller does not care about the implementation of the proxied class, and the modification of the proxied class does not affect the invocation of the high-level module.
- The access permission of the proxy class is closed in the proxy class.
3.2 Forced Proxy
Let’s start with a scene:
Wang Jing wants to find Howie to act, they have known each other for a long time, so Wang Jing calls him directly and asks: “Howie, do you have time? I can findyou in a movie.” Howie replied, “Why don’t you talk to my agent first and check my work schedule?” Then Howie gave Wang Jing the contact information of his agent. After wang Jing talked with her agent, Howie was ready to shoot Wang Jing’s movie.
There is a point in this scene. First of all, Wang Jing can not directly ask Howie to shoot the film. Even if she has contact information, Howie may not shoot for you. Secondly, Wang Jing must communicate with the agent designated by Howie about the specific work. The requirements of compulsory agency are:
- You cannot access the proxied class directly through the proxy class.
- You cannot access the proxied class directly.
- Only the proxy class specified by the proxy class can be heard to access the proxy class.
The next step is to show you how to modify the previous code. First of all, we need to add a method to the abstract topic role to obtain its own proxy class, the rest of the same:
public interface Actor {...public Actor getProxy(a);
}
Copy the code
The star class implements this method because it needs to find its own proxy, and other singing and acting methods also need to check if they are accessed by their own proxy class.
package com.leng.proxy;
/ * * *@Classname Star
* @Date2020/9/12 did *@Autor lengxuezhang
*/
public class Star implements Actor {
private String name;
private Agent agent = null;
public Star(String name) {
this.name = name;
}
@Override
public void act(a) {
if (isProxy()) {
System.out.println(name + "Acting.");
} else {
System.out.println("Please use the specified proxy to access"); }}@Override
public void sing(a) {
if (isProxy()) {
System.out.println(name + "Singing.");
}else {
System.out.println("Please use the specified proxy to access"); }}@Override
public Actor getProxy(a) {
this.agent = new Agent(this);
return this.agent;
}
/** * Determines whether the proxy is specified@return* /
private boolean isProxy(a) {
if(agent == null) {
return false;
}
return true; }}Copy the code
Brokerage human
package com.leng.proxy;
/ * * *@Classname Agent
* @Date2020/9/12 declare *@Autor lengxuezhang
*/
public class Agent implements Actor {
private Actor actor = null;
// Tell agent which "star" I need to contact
public Agent(Actor actor) {
this.actor = actor;
}
@Override
public void act(a) {
this.before();
actor.act();
this.after();
}
@Override
public void sing(a) {
this.before();
actor.sing();
this.after();
}
@Override
public Actor getProxy(a) {
// The broker doesn't have his own broker, so he returns to himself
return this;
}
// Preprocessing method
private void before(a) {
System.out.println("Negotiate the price and sign the contract.");
}
// Post processing method
private void after(a) {
System.out.println("Liquidate performance fees, split stars."); }}Copy the code
Now to test, first see if it works if you access the propped class directly
public class Client {
public static void main(String[] args) {
Star star = new Star("Andy Lau"); star.act(); star.sing(); }}Copy the code
Running result:
Please access using the specified proxy please access using the specified proxyCopy the code
Apparently the access failed. Now try to access it through a proxy class
package com.leng;
import com.leng.proxy.Actor;
import com.leng.proxy.Agent;
import com.leng.proxy.Star;
/ * * *@Classname Client
* @Date 2020/9/12 2:40
* @Autor lengxuezhang
*/
public class Client {
public static void main(String[] args) {
Actor star = new Star("Andy Lau");
Actor agent = newAgent(star); agent.act(); agent.sing(); }}Copy the code
Negotiate the price and sign the contract, please use the designated agent to visit and settle the performance fee, and negotiate the price with the starCopy the code
You can see that the middle business logic is still wrong. Ok, I’ll follow the rules of forced agency:
package com.leng;
import com.leng.proxy.Actor;
import com.leng.proxy.Star;
/ * * *@Classname Client
* @Date 2020/9/12 2:40
* @Autor lengxuezhang
*/
public class Client {
public static void main(String[] args) {
// Define a star first
Actor star = new Star("Andy Lau");
// The star assigns the agentActor agent = star.getProxy(); agent.act(); agent.sing(); }}Copy the code
Negotiate a good price, sign a good contract Andy Lau in acting liquidation performance fee, and star money to negotiate a good price, sign a good contract Andy Lau in singing liquidation performance fee, and star moneyCopy the code
The command output is successful.
Summary: The core of mandatory proxy is to access the methods of the proxy class through the proxy class specified by the proxy class.
Third, summary
This article first introduced the basic concepts and basic code implementation of the proxy pattern. It then extended the concept and implementation of general agents and mandatory agents. The next article will cover dynamic proxies in more detail.
4. References
The Zen of Design Patterns
The last
- If you feel there is a harvest, three consecutive support;
- If there are mistakes in the article, please comment and point out, also welcome to reprint, reprint please indicate the source;
- Personal VX: Listener27, exchange technology, interview, study materials, help the first-line Internet manufacturers in the promotion, etc