java dynamic proxy --proxy & cglib

Outline

  1. proxy
  2. proxy
  3. cglib
  4. summary

 

First, agents

Why use a proxy? In fact, it is hoped, without modifying objects, enhanced object.

Static Agent:

  • Static proxy mode, the proxy class and target class implements the same interface method, the proxy class target class method calls, method calls before and after implementation requires enhanced logic.
  • One problem is that the static agent, each agent class and target class, correspondence, multi-class situation requires the agent, the agent requires a lot of class, it is difficult to maintain.

Dynamic Agent:

  • Dynamic Agent is dynamically generated runtime classes, not at compile time.
  • Dynamic Agent There are two different ways, one is the lower cladding of the reflection jdk Prxoy, one is cglib.

 

Two, Proxy

Proxy proxy object needs to generate a target object implements at least one interface.

Proxy dynamic agent by reflection.

Generate a proxy object to call the Proxy newProxyInstance method.

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

classloader loader- target object

interfaces- target object implements the interface

InvocationHandler- processor, when the interface method of the target object is called a processor invoke method is called in order to achieve dynamic proxy

 

Look at InvocationHandler

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

proxy- proxy object
method is invoked method-
args- parameters passed when calling the method
invoke the proxy method returns a value of the return value

test:

interface:

public interface Speak {
    String say(String content);
}

Target class:

 
 
import lombok.Data;

@Data
public class Person implements Speak{ private String name; private int age; public String say(String content){ System.out.println("hi"+name+age+"content:"+content); return "say return"; } }

Acting factory:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public  class the ProxyFactory {
     // maintain a target object 
    Private Object target;
     public the ProxyFactory (Object target) {
         the this .target = target;
    }
    // generates a proxy object 
    public Object getProxyInstance () {
         return the Proxy.newProxyInstance (
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println ( "before Method:" + method.getName ());
                         // execution of the target object method, return return value. 
                        The returnValue = Object Method.invoke (target, args);
                        System.out.println("end method:"+method.getName());
                        return returnValue;
                    }
                });
    }
}

Proxy object the proxy method calls before and after playing a line of words.

public static void main(String[] args) {
        Person p = new Person();
        p.setAge(11);
        p.setName("xx");
        ProxyFactory factory = new ProxyFactory(p);
        Object proxyInstance = factory.getProxyInstance();
        Speak speak = (Speak) proxyInstance;
        String returnValue = speak.say("haha");
        System.out.println("returnValue:"+returnValue);
    }

 

Three, cglib

Static agents and must implement the interface, but without this restriction cglib, cglib dynamically generated by the subclass bytecode manipulation, so final target class can not be modified.

Similar to the proxy we also need to rewrite a processor

public interface MethodInterceptor extends Callback {
    Object  (Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable;
}

proxy- proxy object
method is invoked method-
methodProxy- proxy method (specifically I is not particularly clear)
Intercept proxy method returns a value of the return value

 

test:

Person does not need to rewrite the implementation of the interface

import lombok.Data;

@Data
public class Person{
    private String name;
    private int age;
    public String say(String content){
        System.out.println("hi"+name+age+"content:"+content);
        return "say return";
    }
}

Acting factory:

import org.assertj.core.internal.cglib.proxy.Enhancer;
import org.assertj.core.internal.cglib.proxy.MethodInterceptor;
import org.assertj.core.internal.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public  class CgProxyFactory <T> {
     // maintenance target object 
    Private T target;
     public CgProxyFactory (T target) {
         the this .target = target;
    }

    // obtain the proxy 
    public T getProxyInstance () {
        Enhancer and = new Enhancer ();
        en.setSuperclass ( the this .target.getClass ());
         // set interceptor 
        en.setCallback ( new new MethodInterceptor () {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("before method:"+method.getName());
                Object returnValue = method.invoke(target, objects);
                System.out.println("end method:"+method.getName());
                return returnValue;
            }
        });
        return (T) en.create();
    }
}

 

And before the proxy objects, hit a line of words before and after the proxy method call.

public static void main(String[] args) {
        Person p = new Person();
        p.setAge(11);
        p.setName("xx");
        CgProxyFactory<Person> factory = new CgProxyFactory(p);
        Person proxyInstance = factory.getProxyInstance();
        String returnValue = proxyInstance.say("cg");
        System.out.println("returnValue:" + returnValue);
    }

 

IV Summary:

  1. Proxy proxy class need to implement the interface, the underlying reflective.
  2. Cglib final proxy object can not be modified, underlying bytecode operation.
  3. The spring will be the case whether the target class implements the interface, the dynamic proxy mode switching may be used to force cglib configure.

 

Guess you like

Origin www.cnblogs.com/liuboyuan/p/11157378.html
Recommended