Java dynamic proxy understanding and Cglib dynamic proxy implementation

  What is the dynamic proxy?

  Under the first static proxy:

  That is, before the program is run, has been compiled classes, this is a static agents,

  Dynamic Agent:

  That is, before the program run, the proxy class does not exist, but the program is running, a dynamic class is dynamically generated proxy class.

  There may be the following thought

  Proxy mode What? What technology?

  Why use a proxy model? What are the benefits?

  Dynamic proxy scenarios What?

  Let us talk about dynamic proxy that implements it:

  The main dynamic proxy using Java reflection technology:

  JavaAPI concerning InvocationHandler so there is generally a description of each agent class must implement this interface InvocationHandler, will be associated with each agent class to a handle,

  When a proxy class method calls will go to the Invoke method InvocationHandler the call.

  The following code is the code references that cattle

  InvocationHandler look at the source code, I'll no longer write it again.

  public interface InvocationHandler

  {

  public abstract Object invoke(Object obj, Method method, Object aobj[])

  throws Throwable;

  }

  Invoke this method has several parameters:

  obj: we represent real objects to call

  method: indicates that a real object of our method to invoke.

  aobj []: representation of a real object method accepts parameters.

  How to use this InvocationHandler this interface, mainly to see the proxy class:

  Proxy is to create a proxy object of the class

  Proxy This class has a method to this: is the most used method

  public static Object newProxyInstance(ClassLoader classloader, Class aclass[], InvocationHandler invocationhandler)

  throws IllegalArgumentException

  parameter:

  classloader: definition of the object loaded by the ClassLoader

  aclass []: which is to provide an interface for the proxy object that represents the proxy object implements these interfaces,

  invocationhandler: that he would associate the proxy method call to an object invocationhandler

  The main dynamic proxy class by Proxy interface invocationhandler:

  Look at specific dynamic proxy to achieve a better understanding:

  1. First is certainly a need for interfaces:

  public interface UserService {

  public String getName(int id);

  public Integer getAge(int id);

  }

  Also we need to implement this interface, which is the proxy object:

  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;

  }

  }

  Also you need to customize a invocationhandler, to realize his invoke methods:

  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;

  }

  }

  }

  Finally, look at how the proxy is to use this interface, as well as the invocationhandler

  import java.lang.reflect.InvocationHandler;

  import java.lang.reflect.Proxy;

  public class TestProxy {

  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));

  }

  }

  Can be seen more clearly understood newproxyInstance is used to generate the proxy proxy object, userService is directed to a particular implementation

  UserServiceImpl

  NewproxyInstance method to pass the actual classLoader, invocationhandler interfaces, and call the class method corresponds to the actual class can be realized:

  System.out.println("++++++before " + method.getName() + "++++++");

  In fact, this line of code above have *** properties, and then discuss in detail aop time.

  This can be seen above use reflective technology to achieve dynamic proxy, we need to define an interface, but sometimes really do not want to define interfaces, can only hope to achieve a good definition of the class, and then you run before the method, after running add some content can be.

  This would be considered a good use of this, but CGLIB CGLIB dynamic proxy is very convenient.

  ASM uses Cglib bytecode technology to generate using the proxy class bytecode. Higher efficiency than the reflection, but the agent is not self final class, clglib elements are integrated proxy class. final class can not be inherited.

  The following look cglib concrete realization:

  Download cglib asm package and package your project need to rely on these two packages:

  First we need a non-final class, and no longer require an interface of reflex

  public class StudentService {

  public String getName(){

  System.out.println("------getName------");

  return "Tom";

  }

  public Integer getID(){

  System.out.println("------getID------");

  return 10;

  }

  }

  Then look at how the agency above class, you need to define an interceptor:

  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;

  }

  }

  Interceptf similar to the above method and invoke methods invocationhandler in by interceptf to really call the method invokeSuper:

  Finally, look Cglb specifically how this class proxy StudentService it:

  import net.sf.cglib.proxy.Enhancer;

  public class TestCglib {

  public static void main(String[] args) {

  CglibProxy cglibProxy = new CglibProxy();

  Enhancer enhancer = new Enhancer();

  enhancer.setSuperclass(StudentService.class);

  enhancer.setCallback(cglibProxy);

  StudentService o = (StudentService)enhancer.create();

  System.out.println(o.getName());

  // System.out.println(o.getID());

  }

  }

  O above that is a proxy class that can access real Studentservice method:

  The result: Wuxi gynecological check how much money http://www.120csfkyy.com/

  ++++++before CGLIB$getName$1++++++

  getName

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

  ++++++before CGLIB$getName$1++++++

  Tom

  Use Cglib so what benefit?

  Look at the code below:

  public class TestCglib {

  public static void main(String[] args) {

  CglibProxy cglibProxy = new CglibProxy();

  Enhancer enhancer = new Enhancer();

  enhancer.setSuperclass(StudentService.class);

  enhancer.setCallback(cglibProxy);

  StudentService o = (StudentService)enhancer.create();

  System.out.println(o.getName());

  // System.out.println(o.getID());

  Enhancer enhancer1 = new Enhancer();

  enhancer1.setSuperclass(UserServiceImpl.class);

  enhancer1.setCallback(cglibProxy);

  UserServiceImpl obj = (UserServiceImpl)enhancer1.create();

  System.out.println(obj.getName(1));

  // System.out.println(o.getID());

  }

  }

  Just write a

  cglibProxy

  Can be achieved

  UserServiceImpl proxy for the StudentService

  Reducing the tedious code, so there is only one agent is enough, followed by easy maintenance, decoupling, if there is a problem, as long as the original class to go on it


Guess you like

Origin blog.51cto.com/14335413/2427338