In-depth analysis of dynamic proxy (on) proxy Methods

Source: Internet
Author: User

There may be fewer explicit use of dynamic proxies, but when it comes to spring interceptor and various transaction management, you will be more familiar with them. That's right, these are at the underlying implementation level, dynamic proxies are all used. To be exact, most dynamic proxies are used to dynamically add functions, such as verification, resource release, and log processing, to a class method.

For smooth transition, let's talk about static proxy first.

Static proxy

The idea of static proxy is simple: put an instance of a real object into the instance of the proxy object, and then call the proxy object method. The proxy object method calls the method of the real object. Take transaction management as an example, as follows:

Userdao
package com.tgb.staticproxy;public interface UserDao {public void add();public void deleteAll();}

Userdaoimpl
Package COM. tgb. staticproxy; public class userdaoimpl implements userdao {public void add () {system. out. println ("add a user to Database");} public void deleteall () {system. out. println ("delete all users ");}}

Userdaoproxy
Package COM. tgb. staticproxy; public class userdaoproxy implements userdao {userdao = NULL; Public userdaoproxy (userdao) {This. userdao = userdao;} public void add () {system. out. println ("enable local transaction"); userdao. add (); system. out. println ("commit or rollback transaction");} public void deleteall () {system. out. println ("enable local transaction"); userdao. deleteall (); system. out. println ("commit or roll back a transaction ");}}
Test

Package COM. tgb. staticproxy; public class test {/*** @ Param ARGs */public static void main (string [] ARGs) {userdao = new userdaoimpl (); userdaoproxy = new userdaoproxy (userdao); // test adding userdaoproxy. add (); system. out. println (".......... separator .......... "); // test userdaoproxy deletion. deleteall ();}}

Execution result

Start a local transaction and add a user to the database to submit or roll back the transaction .......... separator .......... enable local transactions to delete all user committed or rolled back transactions

However, there are a lot of problems with the way the static proxy manages transactions. Every method of each DAO class needs to start and close the transaction, not only the code is duplicated seriously, but the transaction is originally not associated with the business, but coupled together.

Dynamic proxy JDK dynamic proxy

Take transaction management as an example:

Userdao
package com.tgb.dynamicproxy;public interface UserDao {public void add();public void deleteAll();}
Userdaoimpl
Package COM. tgb. dynamicproxy; public class userdaoimpl implements userdao {@ overridepublic void deleteall () {system. out. println ("delete all user information") ;}@ overridepublic void add () {system. out. println ("add a user to Database ");}}
Handler
Package COM. tgb. dynamicproxy; import Java. lang. reflect. invocationhandler; import Java. lang. reflect. method; public class handler implements invocationhandler {private object target; Public handler (Object target?#this.tar get = target ;}@ overridepublic object invoke (Object proxy, method, object [] ARGs) throws throwable {// enable the transaction before (); // executes the business method. invoke (target, argS); // submit or roll back the transaction after (); return NULL;} public void before () {system. out. println ("Start local transaction");} public void after () {system. out. println ("commit or roll back a transaction ");}}
Test
Package COM. tgb. dynamicproxy; import Java. lang. reflect. proxy; public class test {/*** @ Param ARGs */public static void main (string [] ARGs) {try {userdao impl = new userdaoimpl (); handler handler = new handler (impl); userdao proxy = (userdao) proxy. newproxyinstance (impl. getclass (). getclassloader (), impl. getclass (). getinterfaces (), Handler); // test adding proxy. add (); system. out. println (".......... separator .......... "); // test the deletion of proxy. deleteall ();} catch (exception e) {e. printstacktrace ();}}}
Execution result
Start a local transaction to add a user to the database to commit or roll back the transaction .......... separator .......... start local transaction delete all user information commit or rollback transaction

The dynamic proxy of JDK overcomes the static proxy coupling and code duplication issues, but the JDK proxy mode has a serious problem. For example, userdao must have an interface to use JDK dynamic proxy, this greatly limits the scope of JDK dynamic proxy.

Cglib dynamic proxy ASM can dynamically generate bytecode. cglib encapsulates ASM. cglib is not generated for dynamic proxy, but uses its features, but dynamic proxy can be implemented well. Userdaoimpl
Package COM. tgb. cglib; public class userdaoimpl {public void deleteall () {system. out. println ("delete all user information");} public void add () {system. out. println ("add a user to Database ");}}
Cglibproxy
Package COM. tgb. cglib; import Java. lang. reflect. method; import net. SF. cglib. proxy. callback; import net. SF. cglib. proxy. enhancer; import net. SF. cglib. proxy. methodinterceptor; import net. SF. cglib. proxy. methodproxy; public class cglibproxy implements methodinterceptor {private object target; private cglibproxy (object target) {this.tar get = target;} // generate proxy object @ suppresswarnings ("unchecked ") public static <t> T proxytarget (t) {enhancer en = new enhancer (); en. setsuperclass (T. getclass (); en. setcallback (callback) New cglibproxy (t); t TT = (t) en. create (); Return tt;} // execute the interception public object intercept (Object OBJ, method, object [] ARGs, methodproxy proxy) throws throwable {system. out. println ("enable local transaction"); object o = method. invoke (target, argS); system. out. println ("commit or roll back a transaction"); return o ;}}
Test
Package COM. tgb. cglib; public class test {/*** @ Param ARGs */public static void main (string [] ARGs) {// obtain the proxy object userdaoimpl impl = cglibproxy. proxytarget (New userdaoimpl (); // test to add impl. add (); system. out. println (".......... separator .......... "); // test the deletion of impl. deleteall ();}}
Running result
Start a local transaction and add a user to the database to submit or roll back the transaction .......... separator .......... start local transaction delete all user information commit or rollback transaction

We can see that this time, userdaoimpl does not implement any interface to implement the dynamic proxy function.

Summary

This blog was intended to introduce the source code of JDK and cglib dynamic proxies. It was written to introduce the types and implementation methods of proxies. It would take a long time to write more code, so I will describe it in the next blog.




In-depth analysis of dynamic proxy (on) proxy Methods

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.