1. Definition:
Provides a proxy for other objects to control access to this object.
Second, the general class diagram:
Subject abstract subject role
Generic code:
public interface Subject { //define a method public void request(); }
RealSubject specific subject role
Generic code:
public class RealSubject implements Subject { //Implementation public void request() { //Business logic processing } }
Proxy agent theme role: responsible for the application of the real role, and do pre-processing and post-processing work.
public class Proxy implements Subject { //Which implementation class to proxy private Subject subject = null; //default proxy public Proxy(){ this.subject = new Proxy(); } //Pass the proxy through the constructor public Proxy(Object...objects ){ } //implement the method defined in the interface public void request() { this.before(); this.subject.request(); this.after(); } // preprocessing private void before(){ //do something } // deal with the aftermath private void after(){ //do something } }
Under normal circumstances, an interface only needs one proxy class, and the specific proxy class is determined by the high-level module. You can add a constructor to the proxy class Proxy:
public Proxy(Subject _subject){ this.subject = _subject; }
3. Usage scenarios:
Spring AOP is a very typical dynamic proxy.
Fourth, the expansion of the agent model
1. General agent
Require clients to only have access to proxy roles, not real roles
2. Forced proxy
The concept of forced proxy is to find the proxy role from the real role
3. Focus: dynamic proxy
Dynamic proxy does not need to care about who to proxy in the implementation stage, and only specifies which object to proxy in the running stage. That is, the proxy class is dynamically generated
The Java dynamic proxy class is located under the java.lang.reflect package and involves two classes:
(1) Methods defined in the InvocationHandler transaction processor interface
Object invoke (Object obj,Method method,Object[] args)
obj proxy class, method is the proxy method, and args is an array of method parameters. This abstract method is implemented dynamically in the proxy class
(2) Proxy dynamic proxy class
Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
Returns an instance of the proxy class. The returned proxy class can be used as a proxy class.
Implementation steps:
(1) Create a class that implements the interface InvocationHandler, which must implement the invoke method
(2) Create proxied classes and interfaces
(3) Call the static method of Proxy to create a proxy class
(4) Call the method through the proxy
The following takes playing a game as an example to implement dynamic proxy:
Game player interface:
public interface IGamePlayer { //Log in public void login(String user,String password); // Daguai public void killBoss(); //upgrade public void upgrade(); }
Game player implementation class:
public class GamePlayer implements IGamePlayer { private String name = ""; public GamePlayer(String name){ this.name = name; } public void killBoss() { System.out.println(this.name + "打怪"); } public void login(String user, String password) { System.out.println("login name"+user+"user"+this.name+"login successful"); } public void upgrade() { System.out.println(this.name + "Upgrade"); } }
Transaction processor:
public class GamePlayIH implements InvocationHandler { // Proxy instance Object obj = null; //Constructor public GamePlayIH(Object obj){ this.obj = obj; } /** */ call the delegated method * @param proxy the object to be proxied * @param method The method of the proxied object * @param args method parameters * @return method return value * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Start agent"); Object result = method.invoke(this.obj, args); System.out.println("End agent"); return result; } }
Scene class:
public class Client { public static void main(String[] args) throws Throwable { IGamePlayer player = new GamePlayer("wbao"); InvocationHandler handler = new GamePlayIH(player); ClassLoader cl = player.getClass().getClassLoader(); // Dynamically generate a proxy IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, player.getClass().getInterfaces(), handler); proxy.login("wbao", "password"); proxy.killBoss(); proxy.upgrade(); } }
Program execution result:
Start proxy
login wbao user wbao login successfully
ends proxy
start proxy
wbao fight monsters
end proxy
start proxy
wbao upgraded
end proxy
Optimization: Simplify scene class calls and increase notification Advice
Class Diagram: