Java in-depth series (four)--deep analysis of dynamic agent--from static agent to dynamic agent evolution

Source: Internet
Author: User
Tags ticket

Static proxy


For example, before the program executes. The program ape is going to write a Proxy. Then compile, that is, before the program execution, the proxy class bytecode file has been generated (theproxy class file already exists).

static agents, although in the enhancement of existing interface business functions have a great advantage, but a large number of such static agents, the system will make a large number of classes in the scale, difficult to maintain. and the Proxy class and the realsubject class function are essentially the same. Only proxy plays an intermediary role, so the presence of such agents in the system leads to the bloated and loose structure of the system.

In order to solve the problem. Generated a dynamic proxy. Dynamic agent is in the system execution, in the need to proxy the place according to the interface and realsubject dynamic generation proxy class, after the end of use will be destroyed, to avoid Proxy The problem is that the class is redundant in the system.

Take a look at the following examples:

Through the implementation of static proxies. Handwritten bytecode dynamic generation agent:

/* * Ticketing Service Interface */public interface Ticketservice {//Ticket public void sellticket ();//Inquiry public void Inquire ();//refund public void WITHD Raw ();}
/** * Ticketing Service Interface implementation class, station * @author EMILY-T * */public class stations implements Ticketservice {@Overridepublic void Sellticket () {System.out.println ("----------ticket------------");} @Overridepublic void Inquire () {System.out.println ("--------------Inquiry-------------");} @Overridepublic void Withdraw () {System.out.println ("-------------refund--------------");}}
/** * Ticket Point of Sale * * @author emily-t * */public class Stationproxy implements Ticketservice {private station station;//Get,se What is the difference between T and such a constructor? Public Stationproxy (station station) {this.station = station;} @Overridepublic void Sellticket () {// 1. Before doing real business, tips             this.showalertinfo ("xxxx you are using tickets to purchase tickets, each ticket will be charged 5 yuan handling fee!") XXXX ");// 2. Invoke Real business logic            station.sellticket ();//  3. Post-treatment            this.takehandlingfee (); This.showalertinfo ("XXXX welcome you to visit." Good bye! Xxxx\n ");} @Overridepublic void Inquire () {// 1 before doing real business. Tips           this.showalertinfo ("xxxx Welcome to this sale point, the inquiry service will not charge no matter what the fee, This information is for reference only and details are subject to actual station data. XXXX ");// 2. Invoke Real Logic            station.inquire ();// 3. Post-processing            this.showalertinfo ("xxXX welcome you to visit. Good bye! Xxxx\n ");} @Overridepublic void Withdraw () {// 1. Real business pre-processing            this.showalertinfo ("xxxx Welcome to this consignment point, Refunds in addition to the deduction of ticket 20% outside. The agency has an extra charge of 2 yuan!

XXXX ");//2. Call True business logic station.withdraw ();//3. Post-processing This.takehandlingfee ();} /* * Show additional information */private void Showalertinfo (String info) {System.out.println (info);} /* * Charge */private void Takehandlingfee () {System.out.println ("charge for handling fee, print invoice.

。。。 \ n ");}}

public class Test {public static void main (string[] args) throws Exception {Createproxy ();} private static void Createproxy () throws Exception{classpool pool = Classpool.getdefault (); Ctclass cc = Pool.makeclass ("Com.ltt.proxy.StationProxy");//set interface Ctclas Interface1 = Pool.get (" Com.ltt.proxy.TicketService "); Cc.setinterfaces (new Ctclass[]{interface1});//set Fieldctfield field = Ctfield.make (" Private Com.ltt.proxy.Station station; ", CC); Cc.addfield (field); Ctclass Stationclass = Pool.get ("com.ltt.proxy.Station"); ctclass[] arrays = new Ctclass[]{stationclass}; Ctconstructor CTC = Ctnewconstructor.make (ARRAYS,NULL,CTNEWCONSTRUCTOR.PASS_NONE,NULL,NULL,CC);// Set constructor internal information Ctc.stbody ("{this.station=$1;}"); Cc.addconstructor (CTC);//Create Charge procedure Takehandlingfee method Ctmethod Takehandlingfee = Ctmethod.make ("private void Takehandlingfee () {} ", cc), Takehandlingfee.setbody (" System.out.println (\ "charge for handling fee, print invoice \"); Cc.addmethod (Takehandlingfee);//Create Showalertinfo method Ctmethod Showinfo = Ctmethod.make ("private void Showalertinfo (StRing info) {} ", cc); Showinfo.setbody (" System.out.println ($); "); Cc.addmethod (showinfo);//ticket Ctmethod Sellticket = ctmethod.make ("public void Sellticket () {}", cc); Sellticket.setbody ( "{this.showalertinfo (\" xxx) you are using a ticket to purchase tickets. Each ticket will be charged a fee of $5!xxx\ "); + "Station.sellticket ();" + "This.takehandlingfee ();" + "this.showalertinfo (\" XXX Welcome your presence, goodbye! xxxx\ ");}"); Cc.addmethod (Sellticket);//Add Inquire method Ctmethod inquire = Ctmethod.make ("public void Inquire () {}", cc); Inquire.setbody ("{This.showalertinfo (\") XXXX Welcome to this sale point, the inquiry service will not charge no matter what the fee. This inquiry information is only for reference, "+" details to the station real Data!xxxx\ "); + "Station.inquire ();" + "This.showalertinfo (\" xxxx welcome you to visit. Good bye! Xxxx\ ");}"); Cc.addmethod (inquire);//Add Widthraw method Ctmethod withdraw = Ctmethod.make ("public void Withdraw () {}", cc); Withdraw.setbody ("{This.showalertinfo (\" xxxx Welcome to this sales point, refunds in addition to the deduction of ticket 20%, the agency has an additional charge of 2 yuan for the fee!xxxx\ "); + "Station.withdraw ();" + "Station.takehandlingfee ();}"); Cc.addmethod (withdraw);//Get dynamically generated classclass C = Cc.toclass ();//Get constructor constructor constructor = C.getconstructor ( Station.class);//Instantiate ticket by constructorService o = (ticketservice) constructor.newinstance (new station ()); O.inquire (); Cc.writefile ("D://test");}} 

found through the code above. The agents we created manually have a lot of business logic inside. There is a lot of redundancy code, very poor extensibility, and it was intended to reduce redundant code. Decoupled. Instead, it adds redundant code and the difficulty of proxy generation. It is undesirable to assume that business logic is a very complex business.

So the following we are further abstracted, the manual creation of proxy abstraction encapsulation. There are now JDK or CGLIB dynamic agents.

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvbgl1dgvuz3rlbmcxmza=/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma== /dissolve/70/gravity/center ">


It can be seen that the business code is inserted before and after calling the real method. This meansdoing some extra business before or after triggering the real-world role method. In order to construct a proxy class with general-purpose and simplicity, it is possible to give all triggering real-role actions to a trigger manager, which allows the manager to manage triggers uniformly.

Such a manager is Invocationhandler.

        in a static proxy, the proxyProxyall of the methods in this paper make calls to specificRealsubjectthe corresponding method in the. Dynamic agents are the implementation of their own methods to giveInvocationhandlerrole. Outside theProxyThe invocation of each method in the role,Proxywill giveInvocationhandlerto deal with. Invocationhandlerthe role method that invokes the detailed object.

The proxy class should be the same as the real object implementation function. So there are two ways of doing this:

1 , proxy classes, and real objects implement the same interface

2 realsubject proxy with realsubject realsubject The method to achieve polymorphism.

so these two ways are each: The first kind is JDK dynamic Proxy implementation, and the other is CGLIB implementation of the method.


In principle, it is not difficult to understand the JDK dynamic agent and the CGLIB dynamic Agent. are solved by a step-by-step abstraction package to solve some kind of problem. The process of generating a detailed application scenario.

Java in-depth series (four)--deep analysis of dynamic agent--from static agent to dynamic agent evolution

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.