1. JDK proxy example
JDK dynamic agent can only generate agent for the class that implements the interface, not for class agent. JDK dynamic agent needs the following classes: interface, implementation class, and agent class that implements the InvocationHandler interface (this class includes the following methods: the constructor that can be passed into the target object, and the implementation of InvocationHandler interface method can execute the target method to get the proxy of the target object Object)
The code example is as follows: Interface
package jicu.proxy.jdk; public interface Print { void printWords(); void printNumbers(); }
Implementation class:
package jicu.proxy.jdk; public class PrintImpl implements Print { public PrintImpl() { // TODO Auto-generated constructor stub } @Override public void printWords() { // TODO Auto-generated method stub System.out.println("this is PrintImpl printWords()"); } @Override public void printNumbers() { // TODO Auto-generated method stub System.out.println("this is PrintImpl printNumbers()"); } }
Proxy class:
package jicu.proxy.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler { private Object object; /** * Construction method passed in target object * * @param object */ public JdkProxy(Object object) { // TODO Auto-generated constructor stub this.object = object; } /** * Method of executing target object */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("before method invoke"); // Method of executing target object Object o = method.invoke(object, args); System.out.println("after method invoke"); return o; } /** * Get the proxy object of the target object * * @return */ public Object getProxy() { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), object.getClass().getInterfaces(), this); } }
Test method:
package jicu.proxy.jdk; public class TestMain { public static void main(String[] args) { // TODO Auto-generated method stub // Target object Print print = new PrintImpl(); // proxy class JdkProxy jdkProxy = new JdkProxy(print); // Proxy object Print printProxy = (Print) jdkProxy.getProxy(); printProxy.printWords(); printProxy.printNumbers(); } }
2. cglib is a proxy for class implementation. It mainly generates a subclass for the specified class, covering the methods. The bottom layer is to transform the bytecode and generate a new class by using a small and block bytecode processing framework ASM
cglib proxy example
package soundsystem; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class CglibProxy { public static void main(String[] args) { // TODO Auto-generated method stub Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(CglibProxy.class); enhancer.setCallback(new MethodInterceptorImpl()); // Build proxy object CglibProxy cgPxocy = (CglibProxy) enhancer.create(); cgPxocy.test(); } public void test() { // TODO Auto-generated method stub System.out.println("this is CglibProxy test()"); } /** * Call target method through proxy object * * @author timi * */ private static class MethodInterceptorImpl implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // TODO Auto-generated method stub System.out.println("before invoke"); Object o = proxy.invokeSuper(obj, args); System.out.println("after invoke"); return o; } } }