Summary of dynamic proxy
1. Dynamic proxy Classification
We designed an Application Scenario:
When I was looking for an actor from a previous director's cast, I went to the house to ask the actor to talk about the price. However, with the development of the times, there was an economic company and a contract with the actor. Now it is necessary for actors to directly seek economic companies rather than actors.
1.1 interface-based Dynamic proxy
// Create an actor role public class Actor implements iactor {? /*** Basic Performance ** @ Param money */@ override public void basicact (float money) {system. out. println ("Get the money and start the basic performances:" + money );}? /*** Dangerous performances ** @ Param money */@ override public void dangeract (float money) {system. out. println ("Get the money and start a dangerous performance:" + money );}}??? // Simulate economic companies' standard public interface iactor {/***** basic performances * @ Param money */Public void basicact (float money ); /*** dangerous performances ** @ Param money */Public void dangeract (float money );}
?
Then we simulate a cast and find actors through economic companies, but economic companies also have their own standards, that is, the parameter money
Public class client {? Public static void main (string [] ARGs) {// early stage: go directly to the home and find actor = new actor ();? // Come to the actor through a brokerage company? Iactor proxyactor = (iactor) proxy. newproxyinstance (actor. getclass (). getclassloader (), actor. getclass (). getinterfaces (), new invocationhandler () {/*** here provides enhanced code * This method is used to execute any method of the proxy object. * @ Param proxy refers to the reference of the proxy object * @ Param method the method currently executed * @ Param ARGs the parameters required by the current method * @ return has the same return value as the method of the proxy object *@ throws throwable */@ override public object invoke (Object proxy, method method, object [] ARGs) throws throwable {object rtvalue = NULL; // 1. retrieve the current method parameter float money = (float) ARGs [0]; // 2. determine the method. If ("basicact ". equals (method. getname () {// Basic Performance: extract 20%. If (money> 5000f) {rtvalue = method, more than 5000 pieces are required for a day. I Nvoke (actor, money * 0.8f) ;}} if ("dangeract ". equals (method. getname () {// high-risk performance: 10% of the total number of results is selected. If (money> 20000f) {rtvalue = method, more than 20000 pieces are required for a day. invoke (actor, money * 0.9f) ;}} return rtvalue ;}});?? Proxyactor. basicact (0000f); proxyactor. dangeract (50000f );}}?
Running result:
Get the money and start the basic performances: 8000.0 get the money and start the dangerous performances: 45000.0
Summary:
Dynamic proxy BASED ON INTERFACE
* Function: enhances existing methods without modifying source code.
* Feature: bytecode is created with use and loaded with use.
* Interface-based Dynamic Proxy:
* Provider: JDK official
* Requirement: the proxy object must implement at least one interface.
* Involved classes: proxy
* Involved method: newproxyinstance
* Method parameters:
* Classloader: class loader. Load the byte code of the proxy object. Use the same class loader as the proxy object. Fixed statement.
* Class []: an array of bytecode. The method that the proxy object has. The same interface as the proxy object.
* If the proxy object itself is an interface, the proxy object will be directly stored in the bytecode array.
* XXX. getclass (). getinterfaces () | new class [] {XXX}
* Fixed statement.
* Invocationhandler: proxy interface. Who writes it. Used to enhance the method. We need to provide an implementation class for this interface.
* Generally, it can be written as an anonymous internal class.
* Policy mode:
* Data already exists
* The purpose is clear.
* The process of achieving the goal is strategy.
1.2 subclass-based Dynamic proxy
Public class actor {? /*** Basic Performance ** @ Param money */? Public void basicact (float money) {system. Out. println ("Get the money and start the basic performance cglib:" + money );}? /*** Dangerous performances */? Public void dangeract (float money) {system. Out. println ("Get the money and start a dangerous performance cglib:" + money );}}???? Public class client {? Public static void main (string [] ARGs) {// early stage: go directly to the house to find // actor = new actor (); // use a brokerage company to find actor/*** dynamic proxy **. function: Enhance existing methods without modifying the source code. * feature: bytecode is created on demand, load as needed. * Subclass-based Dynamic Proxy: * provider: third-party cglib library * requirement: the proxy object cannot be the final class. Class that cannot be modified by final *: The method involved by enhancer *: parameter of the create * method: * Class: bytecode. The byte code of the proxy object. Fixed syntax .? * Callback: proxy interface. Who writes it. Used to enhance the method. We need to provide an implementation class for this interface. * Generally, it can be written as an anonymous internal class. * We need to use its sub-interface: methodinterceptor * policy mode: * data has been clearly defined. * The process of achieving the goal is strategy. **/Actor cglibactor = (actor) enhancer. create (actor. getclass (), new methodinterceptor () {/*** here provides enhanced code * This method is used to execute any method of the proxy object. * @ Param proxy object reference * @ Param method currently executed Method * @ Param ARGs parameters required for the current method * @ Param methodproxy proxy object for the current method * @ return and proxy the object method has the same return value * @ throws throwable */@ override public object intercept (Object proxy, method method, object [] ARGs, methodproxy) throws throwable {object rtvalue = NULL; // 1. retrieve the current method parameter float money = (float) ARGs [0]; // 2. determine the method. If ("basicact ". equals (method. getname () {// Basic Performance: extract 20%. If (money> 5000f) {rtvalue = method, more than 5000 pieces are required for a day. invoke (actor, money * 0.75f);} If ("dangeract ". equals (method. getname () {// high-risk performance: 10% of the total number of results is selected. If (money> 20000f) {rtvalue = method, more than 20000 pieces are required for a day. invoke (actor, money * 0.85f) ;}} return rtvalue ;}}); cglibactor. basicact (cmdf); cglibactor. dangeract (50000f );}}
The dynamic proxy is clear at a glance.