Two ways to implement Java dynamic Proxy

Source: Internet
Author: User
Tags aop object object reflection throwable

The blocking capabilities of AOP are implemented by dynamic proxies in Java. To be blunt, it is to increase the slice logic on the basis of the target class, and to generate the enhanced target class (the slice logic either before the target class function executes or after the target class function executes, or when the target class function throws an exception). The different timing of the cut corresponds to different types of interceptor, such as Beforeadviseinterceptor,afteradviseinterceptor and Throwsadviseinterceptor.

So how does a dynamic proxy weave the slice logic (advise) into the target class method? Here's a detailed introduction and implementation of the two dynamic proxies used in AOP.

AOP's source code uses two kinds of dynamic agents to achieve the interception into the function: JDK dynamic proxy and cglib dynamic agent. Both methods exist at the same time, each has its advantages and disadvantages. The JDK dynamic proxy is realized by the reflection mechanism in Java, and the cglib dynamic proxy is realized by using ASM. In general, the reflection mechanism is more efficient in generating classes, and ASM is more efficient in the execution of the class after it is generated (you can solve the ASM generation class process inefficiencies by caching the ASM-generated classes). It is also important to note that the application of the JDK dynamic proxy must be the target class based on a unified interface. Without the above prerequisites, the JDK dynamic proxy cannot be applied. It can be seen that the JDK dynamic proxy has some limitations, cglib this third-party library implementation of dynamic proxy application is more extensive, and more efficient in the advantages.

1. Define interfaces and implementations

Package com.meituan.hyt.test3.service;


Public interface UserService {
Public String getName (int id);

Public Integer getage (int id);
}
Package Com.meituan.hyt.test3.service.impl;

Import Com.meituan.hyt.test3.service.UserService;


public class Userserviceimpl implements UserService {
@Override
Public String getName (int id) {
SYSTEM.OUT.PRINTLN ("------getName------");
return "Tom";
}

@Override
Public Integer getage (int id) {
SYSTEM.OUT.PRINTLN ("------getage------");
return 10;
}
}
2, JDK dynamic Proxy implementation

Package com.meituan.hyt.test3.jdk;

Import Java.lang.reflect.InvocationHandler;
Import Java.lang.reflect.Method;


public class Myinvocationhandler implements Invocationhandler {
Private Object target;

Myinvocationhandler () {
Super ();
}

Myinvocationhandler (Object target) {
Super ();
This.target = target;
}

@Override
public object invoke (object O, Method method, object[] args) throws Throwable {
if ("GetName". Equals (Method.getname ()) {
System.out.println ("++++++before" + method.getname () + "++++++");
Object result = Method.invoke (target, args);
System.out.println ("++++++after" + method.getname () + "++++++");
return result;
}else{
Object result = Method.invoke (target, args);
return result;
}

}
}
Package com.meituan.hyt.test3.jdk;

Import Com.meituan.hyt.test3.service.UserService;
Import Com.meituan.hyt.test3.service.impl.UserServiceImpl;

Import Java.lang.reflect.InvocationHandler;
Import Java.lang.reflect.Proxy;


public class Main1 {
public static void Main (string[] args) {
UserService userservice = new Userserviceimpl ();
Invocationhandler Invocationhandler = new Myinvocationhandler (userservice);
UserService userserviceproxy = (userservice) proxy.newproxyinstance (Userservice.getclass (). GetClassLoader (),
Userservice.getclass (). Getinterfaces (), Invocationhandler);
System.out.println (Userserviceproxy.getname (1));
System.out.println (Userserviceproxy.getage (1));
}
}
Run results

++++++before getname++++++

------getName------

++++++after getname++++++

Tom

------getage------

10

3, Cglib dynamic Proxy implementation

Cglib is an excellent dynamic proxy framework that uses ASM to dynamically generate subclasses of proxy classes in memory, using Cglib to implement dynamic proxy functionality even if the proxy class does not implement any interfaces. Cglib is simple to use and runs much faster than the proxy dynamic proxy for JDK:

Cglib's core classes:

net.sf.cglib.proxy.enhancer– Main Enhancement class

net.sf.cglib.proxy.methodinterceptor– the main method of intercepting the class, it is the callback interface, the user needs to implement

The proxy class of the Java.lang.reflect.Method class of NET.SF.CGLIB.PROXY.METHODPROXY–JDK can conveniently implement the invocation of the source object method, such as:

Object o = Methodproxy.invokesuper (proxy, args);//Although the first argument is a proxy object, there is no question of a dead loop.

The Net.sf.cglib.proxy.MethodInterceptor interface is the most versatile type of callback (callback), which is often used by agent-based AOP to implement the call to intercept (intercept) methods. This interface defines only one method

public object Intercept (object object, Java.lang.reflect.Method method,

Object[] args, Methodproxy proxy) throws Throwable;

The first parameter is the proxy pair, and the second and third parameters are the parameters of the method and method of blocking. The original method may be invoked by using a generic reflection of the Java.lang.reflect.Method object, or by using a Net.sf.cglib.proxy.MethodProxy object. Net.sf.cglib.proxy.MethodProxy is usually preferred to use because it is faster.

Package com.meituan.hyt.test3.cglib;


Import Net.sf.cglib.proxy.MethodInterceptor;
Import Net.sf.cglib.proxy.MethodProxy;

Import Java.lang.reflect.Method;


public class Cglibproxy implements Methodinterceptor {
@Override
public Object intercept (object O, Method method, object[] args, Methodproxy methodproxy) throws Throwable {
System.out.println ("++++++before" + methodproxy.getsupername () + "++++++");
System.out.println (Method.getname ());
Object O1 = Methodproxy.invokesuper (o, args);
System.out.println ("++++++before" + methodproxy.getsupername () + "++++++");
return O1;
}
}
Package com.meituan.hyt.test3.cglib;

Import Com.meituan.hyt.test3.service.UserService;
Import Com.meituan.hyt.test3.service.impl.UserServiceImpl;
Import Net.sf.cglib.proxy.Enhancer;

public class Main2 {
public static void Main (string[] args) {
Cglibproxy cglibproxy = new Cglibproxy ();

Enhancer enhancer = new enhancer ();
Enhancer.setsuperclass (Userserviceimpl.class);
Enhancer.setcallback (Cglibproxy);

UserService o = (userservice) enhancer.create ();
O.getname (1);
O.getage (1);
}
}
Run Result:

++++++before cglib$getname$0++++++

GetName

------getName------

++++++before cglib$getname$0++++++

++++++before cglib$getage$1++++++

Getage

------getage------

++++++before cglib$getage$1++++++

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.