Dynamic proxy and its two implementations (JDK, CGLIB)

Source: Internet
Author: User

What is proxy mode

Provides an agent for an object to access it through a proxy.

Role composition of proxy mode

The proxy mode consists of three roles:

Abstract role: A business method that declares the real role implementation through an interface or abstract class.
Proxy role: the implementation of abstract role, is the real role of the agent, through the real role of the business logic method to implement the abstract method, and can attach their own operations.
Real role: Implement abstract roles, define the business logic that the real role will implement, and be called by the proxy role.

My summary:

An abstract role is an interface or abstract class that defines some methods;
The real role is to implement the abstract role and the method thereof;
Proxy roles also implement abstract roles, inject real roles, provide methods that have the same name as real roles, and invoke real-world roles through injected real-world roles in a method with the same name as the proxy role.

The role of proxy mode

High scalability:
For example, a method in interface a needs to be called by two real characters (B, C), now there are new requirements, need to modify B to implement the interface a method m, the direct modification of B will affect the stability of the system, create an agent Proxyb Implement interface A, and the real object B injected in. PROXYB implements the interface method M, in addition to adding additional behavior, and then invoking the m of real object B. Thus achieved "to modify the closure, open to expansion", to ensure the stability of the system.

Clear responsibilities: The typical example is the application of AOP, in a business class that inherits an interface call, in order to log, create a proxy class of the business class, and inject the business class in the proxy class, and implement the method of this interface, in the method can be added to the log record code, The method in the business class is then invoked through the injected business class, which enables the addition of the log function.

Static Proxy and implementation concepts: created by programmers or tools to generate proxy class source code, and then compile the proxy class. Realize:

Take a look at the example
1. Abstract role (interface):

package com.proxy.test;publicinterface UserService {    publicvoidaddUser();}

2. Real role (Implementation Class):

package com.proxy.test;publicclass UserServiceImpl implements UserService{    @Override    publicvoidaddUser() {        System.out.println("增加用户中...");    }}

3. Proxy roles (implementing proxy classes)

 PackageCom.proxy.test; Public  class userserviceproxy implements userservice{          PrivateUserService UserService; Public Userserviceproxy(UserService UserService) { This. Setuserservice (UserService); } PublicUserServiceGetuserservice() {returnUserService; } Public void Setuserservice(UserService UserService) { This. UserService = UserService; }@Override         Public void AddUser() {System.out.println ("Increase user readiness ...");        Userservice.adduser (); System.out.println ("Add user end ..."); }}

4. Operation Result:

增加用户准备...增加用户中...增加用户结束...

Is there much like the implementation of logging capabilities?

But static proxies also have some drawbacks:
1. Once the interface adds a method, the class implementing the interface implements this method, including the proxy class, which makes the code maintenance difficult.
2. The proxy object can only serve an object, and if there are many objects that require a proxy, the amount of code is large.
At this point we need dynamic proxies.

JDK Dynamic agent and implementation principle:

The Java reflection mechanism can generate any type of dynamic proxy class. The proxy class and the Invocationhandler interface under the Java.lang.reflect package provide the ability to generate dynamic proxy classes.

Practice:

1. Abstract role (Create an interface):

package com.jdkproxy.test;publicinterface UserService {    publicvoidaddUser();}

2. Real role (Implementation interface):

package com.jdkproxy.test;import com.proxy.test.UserService;publicclass UserServiceImpl implements UserService{    @Override    publicvoidaddUser() {        System.out.println("增加用户中...");    }}

3. Proxy role:

package com.jdkproxy.test;publicclass addLogs {    publicvoidaddLog(){        System.out.println("增加用户日志启动");    }}

4. Dynamic proxy class (must implement Invocationhandler interface)

 PackageCom.jdkproxy.test;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method; Public  class jdkproxy implements Invocationhandler {    //target object    PrivateObject Target;PrivateAddlogs logger =NewAddlogs (); Public Jdkproxy() {    } PublicObjectGettarget() {returnTarget } Public void settarget(Object target) { This. target = target; } PublicAddlogsGetLogger() {returnLogger } Public void Setlogger(Addlogs logger) { This. Logger = logger; } Public Jdkproxy(Object target) { This. target = target; }//Parameter 1 proxy object to be generated in the future    //Parameter 2 image of the real method inside the target object to be called in the future    //Parameter 3 The arguments passed when the method is called in the future     PublicObjectInvoke(Object Proxy, Method m, object[] args)throwsThrowable {//Get the name of the method to be called in the futureString methodName = M.getname ();//Log out for a bitSystem.out.println (methodname+"is invocation"); Logger.addlog ();//Use reflection to invoke methods that need to be actually called in the future.Object o = M.invoke (target, args);returnO }   }

5. Testing

 PackageCom.jdkproxy.test;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Proxy;ImportCom.proxy.test.UserService;ImportCom.proxy.test.UserServiceImpl; Public  class testjdkproxy {     Public Static void Main(string[] args) {UserService userservice=NewUserserviceimpl (); Class C = Userservice.getclass ();//Get the Class loader object for the target objectClassLoader ClassLoader = C.getclassloader ();//Get all interfaces implemented by the target objectClass[] interfaces = C.getinterfaces ();//Obtain an implementation class object for the Invocationhandler interface and pass the target object inInvocationhandler h =NewJdkproxy (UserService);//Parameter 1 class loader object for the target object            //Parameter 2 all interfaces implemented by the target object. Array of class type            //Parameter 3 implementation class object for the Invocationhandler interfaceUserService proxy = (userservice) proxy.newproxyinstance (ClassLoader, interfaces, h);//Proxy is an object that implements the dynamically generated proxy class for the Istudentservice interface.Proxy.adduser (); }}

6. Operation Result:

addUseris invocation增加用户日志启动增加用户中...

7. Analysis:
Let's look at the dynamic proxy class:

publicMethod m, Object[] args)            throws Throwable {        // 获得将来所调用方法的名字        String methodName = m.getName();        // 用日志记录输出一下        System.out.println(methodName+"is invocation");        logger.addLog();        // 用反射的方式去调用将来需要真正调用的方法.        Object o = m.invoke(target, args);        return o;    }

Each dynamic proxy class must implement the Invocationhandler interface, and each instance of the proxy class is associated with a handler.

When we call a method through a proxy object, the invocation of this method is forwarded to the Invoke method of the Invocationhandler interface.

publicMethod m, Object[] args)            throws Throwable {}

Proxy: Refers to the real object that we are acting for
Method: Refers to the methods object that we want to invoke the real object
Args: Refers to parameters that are accepted when a method of a real object is called
Methods of Reflection in code
Object o = m.invoke(target, args);
To invoke the method of the real character, before and after this method we can join the log record and so on.

In the test class:

     Public Static void Main(string[] args) {UserService userservice=NewUserserviceimpl (); Class C = Userservice.getclass ();//Get the Class loader object for the target objectClassLoader ClassLoader = C.getclassloader ();//Get all interfaces implemented by the target objectClass[] interfaces = C.getinterfaces ();//Obtain an implementation class object for the Invocationhandler interface and pass the target object inInvocationhandler h =NewJdkproxy (UserService);//Parameter 1 class loader object for the target object            //Parameter 2 all interfaces implemented by the target object. Array of class type            //Parameter 3 implementation class object for the Invocationhandler interfaceUserService proxy = (userservice) proxy.newproxyinstance (ClassLoader, interfaces, h);//Proxy is an object that implements the dynamically generated proxy class for the Istudentservice interface.Proxy.adduser (); }

The core code is:

 UserService proxy =                 (UserService)Proxy.newProxyInstance                (classLoader, interfaces, h);

The function of the proxy class is to create a class that dynamically creates a proxy object.

The newproxyinstance of proxy gets a dynamic proxy object, passing in three parameters:

ClassLoader: A ClassLoader object that defines which ClassLoader object to load on the generated proxy object

Interfaces: An array of interface objects, which means that I'm going to provide a set of interfaces to the object I need to proxy, and if I provide a set of interfaces to it, then this proxy object declares that the interface is implemented (polymorphic) so that I can invoke the methods in this set of interfaces.

H: A Invocationhandler object that represents the Invocationhandler object to which the dynamic proxy object is associated when it invokes the method.

Look at this sentence again:

InvocationHandler h =                     new JDKProxy(userService);

We're going to proxy which real object, we'll pass the object in, and finally we'll call its method through the real object.
More information: http://www.cnblogs.com/xiaoluo501395377/p/3383130.html

Cglib Dynamic agent and implementation

Dynamic proxy and its two implementations (JDK, CGLIB)

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.