A brief description of three kinds of proxy modes in Java

Source: Internet
Author: User
Tags throwable

This article focuses on three kinds of proxy mode in Java code How to write, in order to ensure the relevance of the article, for the moment do not discuss the underlying implementation principle, the specific principles will be described in the next blog post.

What is the proxy mode?

Proxy mode is a kind of design pattern, which is simply to extend the function of the target object without changing the source code .

For example, there is a singer object called singer, this object has a singing method called Sing ().

1  Public class singer{2      Public void Sing () {3         System.out.println ("Sing a Song"); 4     }  5 }

If you want to, through some of your way to produce the singer object, before and after the singing to the audience to say hello and appreciation, that is, the target object Singer sing method to expand the function.

1  Public void Sing () {2     System.out.println ("Say hello to the audience");  3     System.out.println ("Sing a Song");   4     SYSTEM.OUT.PRINTLN ("Thank You");  5 }  

But often you can not directly modify the source code , it may be that you want the original object to remain the same as the original, or you provide just a pluggable plug-in, and even you may not know which target object you want to extend. In this case, you need to use the Java proxy mode. On the Internet a lot of examples of managers in life to explain the "agent", it seems easy to understand, but I think it is not suitable for programmers to comprehend. Programmers should start with the nature of the code.

Three types of proxy modes in Java

There are three ways to achieve the above requirements, this part we only look at three patterns of code how to write, first not involved in the implementation of the principle of the part.

1. Static Proxy
1  Public InterfaceIsinger {2     voidsing ();3 }4 5 /**6 * The target object implements an interface7  */8  Public classSingerImplementsisinger{9      Public voidSing () {TenSystem.out.println ("Sing a Song"); One     }   A } -  - /** the * Proxy objects and target objects implement the same interface -  */ -  Public classSingerproxyImplementsisinger{ -     //receives the target object so that the Sing method is called +     PrivateIsinger Target; -      PublicUserdaoproxy (Isinger target) { +          This. target=Target; A     } at     //functional extension of the Sing method of the target object -      Public voidSing () {  System.out.println ("Say hello to the audience");  - target.sing ();  System.out.println ("Thank You");  -     } in}

Test

1 /**2 * Test Class3  */4  Public classTest {5      Public Static voidMain (string[] args) {6         //target Object7Isinger target =NewSinger ();8         //Proxy Object9Isinger proxy =NewSingerproxy (target);Ten         //The method that performs the proxy One proxy.sing (); A     } -}

Summary: In fact, the thing to do here is to create a proxy class Singerproxy, inherit the Isinger interface and implement the method. It's just that this implementation deliberately includes the method of the target object, which makes it look like a way to "extend" the target object. If the proxy object is simply another implementation of the Sing method without a method that contains the target object, it cannot be counted as a proxy mode. So the inclusion here is the key.

  Disadvantage: This implementation is very intuitive and simple, but its disadvantage is that the proxy object must be written in advance , if the interface layer has changed, the code of the proxy object should also be maintained. If you can write the proxy object dynamically at run time, it not only reduces the code of a large number of proxy classes, but also less the trouble of constant maintenance, but the efficiency of running time must be affected. This approach is the next dynamic agent.

2. Dynamic Agent (also known as JDK agent)

As with static proxies, the singer object is still extended

1  Public InterfaceIsinger {2     voidsing ();3 }4 5 /**6 * The target object implements an interface7  */8  Public classSingerImplementsisinger{9      Public voidSing () {TenSystem.out.println ("Sing a Song"); One     }   A}

This time, the code is very simple and the format is basically fixed because the Java layer encapsulates the implementation details (which is detailed later).

Call the static method of the proxy class Newproxyinstance, the method returns the proxy class object

Static Object newproxyinstance (ClassLoader loader, class<?>[] Interfaces,invocationhandler h)

The three parameters received in turn are:

    • ClassLoader loader:Specifies that the current target object uses the ClassLoader, fixed
    • Class<?>[] interfaces:The type of interface implemented by the target object, fixed
    • InvocationHandler h: An event handler interface that needs to pass in an implementation class, typically using anonymous internal classes directly

Test code

1  Public classtest{2      Public Static voidMain (string[] args) { 3 Singer target = new  Singer (); 4Isinger proxy =(Isinger) proxy.newproxyinstance (5 Target.getclass (). getClassLoader (),6 Target.getclass (). Getinterfaces (),7                 NewInvocationhandler () {8 @Override9                      PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable {Ten                         System.out.println ("Say hello to the audience");  One                         //execute target object method AObject returnvalue =Method.invoke (target, args); -                        System.out.println ("Thank You");  -                         returnreturnvalue; the                     } -                 }); - proxy.sing (); -     } +}

Summary: The above code only the yellow part of the need to write their own, the rest are all fixed code. Because Java encapsulates the implementation details of the Newproxyinstance method, it is so convenient to use, and the underlying principles will be explained in the next section.

disadvantage: It can be seen that the static agent and the JDK agent have a common disadvantage is that the target object must implement one or more interfaces, join No, you can use the Cglib proxy.

3.Cglib Proxy

Prerequisites:

    • The Cglib jar file needs to be introduced, and since the Cglib feature is already included in spring's core package, it can be introduced directly Spring-core-3.2.5.jar
    • The target class cannot be final
    • If the target object's method is final/static, then it will not be intercepted, that is, the target object's additional business methods will not be executed.
1 /** 2 * target object, no interface implemented 3  */ 4  Public class singer{56      Public void Sing () {7         System.out.println ("Sing a Song"); 8     }9 }
1 /**2 * Cglib sub-class agent factory3  */4  Public classProxyfactoryImplementsmethodinterceptor{5     // Maintaining target objects6     PrivateObject Target;7 8      Publicproxyfactory (Object target) {9          This. target =Target;Ten     } One  A     // Create a proxy object for the target object -      PublicObject getproxyinstance () { -         //1. Tool Class theEnhancer en =Newenhancer (); -         //2. Set the parent class - En.setsuperclass (Target.getclass ()); -         //3. Setting the callback function +En.setcallback ( This); -         //4. Creating subclasses (proxy objects) +         returnen.create (); A     } at  - @Override -      PublicObject Intercept (Object obj, Method method, object[] args, Methodproxy proxy)throwsThrowable {  System.out.println ("Say hello to the audience");  -         //methods for executing target objects -Object returnvalue =Method.invoke (target, args);  System.out.println ("Thank You");  -         returnreturnvalue; to     } +}

Here the code is also very fixed, only the yellow part of the need to write their own

Test

1 /**2 * Test Class3  */4  Public classtest{5      Public Static voidMain (string[] args) {6         //target Object7Singer target =NewSinger ();8         //Proxy Object9Singer proxy = (Singer)Newproxyfactory (target). Getproxyinstance ();Ten         //methods for executing proxy objects One proxy.sing (); A     } -}

Conclusion: The three kinds of agent models have advantages and disadvantages and corresponding applicable scope, mainly see whether the target object realizes the interface. Example of the proxy pattern selected with the spring framework

In spring's AOP programming:
If the target object that joins the container has an implementation interface, use the JDK proxy
If the target object does not implement an interface, use the Cglib proxy

The next blog post will detail the underlying principles of dynamic agents and cglib agents, so stay tuned.

A brief description of three kinds of proxy modes in Java

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.