Simple implementation of JDK dynamic agent and cglib agent mode in aop

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

	}

}

Tags: JDK Java

Posted on Tue, 05 May 2020 18:46:56 -0400 by Rose.S