Java动态代理和Cglib

JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,这就是为什么采用动态代理时为什么只能用接口引用指向代理,而不能用传入的类引用执行动态类。

cglib采用的是用创建一个继承实现类的子类,用asm库动态修改子类的代码来实现的,所以可以用传入的类引用执行代理类

动态代理
package proxy.test;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JAVA动态代理实现AOP
 * 
 * from internet
 */
public class AopTest {

	public static void main(String[] args) {

		Before before = new Before() {
			public void before() {
				System.out.println("...before...");
			}
		};

		After after = new After() {
			public void after() {
				System.out.println("...after...");
			}
		};

		Hello hello = null;

		// 普通方法执行
		System.out.println("-------------普通执行-------------");
		hello = new HelloEnglish();
		hello.sayHello("bao110908");
		hello.sayHi("bao110908");
		System.out.println();

		// 切入方法执行前(前置增强)
		System.out.println("-------------前置增强-------------");
		hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before);
		hello.sayHello("bao110908");
		hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入
		System.out.println();

		// 切入方法执行后(后置增强)
		System.out.println("-------------后置增强-------------");
		hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after);
		hello.sayHello("bao110908");
		hello.sayHi("bao110908");
		System.out.println();

		// 切入方法执行前和执行后(环绕增强)
		System.out.println("-------------环绕增强-------------");
		hello = HelloAopManager
				.getHelloProxy(new HelloEnglish(), before, after);
		hello.sayHello("bao110908");
		hello.sayHi("bao110908");
		System.out.println();
	}
}

@Retention(RetentionPolicy.RUNTIME)
@interface Enhancement {
}

interface Hello {
	@Enhancement
	public void sayHello(String name);

	public void sayHi(String name);
}

class HelloChinese implements Hello {
	public void sayHello(String name) {
		System.out.println(name + ",您好");
	}

	public void sayHi(String name) {
		System.out.println("哈啰," + name);
	}
}

class HelloEnglish implements Hello {
	public void sayHello(String name) {
		System.out.println("Hello, " + name);
	}

	public void sayHi(String name) {
		System.out.println("hi, " + name);
	}
}

class HelloAopManager {
	private HelloAopManager() {
	}

	public static Hello getHelloProxy(Hello hello, Before before) {
		return getHelloProxy(hello, before, null);
	}

	public static Hello getHelloProxy(Hello hello, After after) {
		return getHelloProxy(hello, null, after);
	}

	public static Hello getHelloProxy(Hello hello, Before before, After after) {
		HelloHandler handler = new HelloHandler();
		if (before != null) {
			handler.setBefore(before);
		}
		if (after != null) {
			handler.setAfter(after);
		}
		return handler.bind(hello);
	}
}

/**
 * 前置增强接口
 */
interface Before {
	public void before();
}

/**
 * 后置增强接口
 */
interface After {
	public void after();
}

class HelloHandler implements InvocationHandler {

	/**
	 * 需要进行代理的实例
	 */
	private Hello hello = null;

	/**
	 * 前置增强
	 */
	private Before before = null;

	/**
	 * 后置增强
	 */
	private After after = null;

	/**
	 * InvocationHandler 接口的实现方法,进行动态代理
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// 看看接口中方法是否标注了需要 Enhancement
		boolean b = method.isAnnotationPresent(Enhancement.class);
		if (!b) {
			// 没有标注的话,按原方法执行
			return method.invoke(hello, args);
		}
		// 有标注的话,进行方法的前置和后置增强
		if (before != null) {
			before.before();
		}
		Object obj = method.invoke(hello, args);
		if (after != null) {
			after.after();
		}
		return obj;
	}

	/**
	 * 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例
	 * 
	 * @param hello
	 * @return
	 */
	public Hello bind(Hello hello) {
		this.hello = hello;
		Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass()
				.getClassLoader(), hello.getClass().getInterfaces(), this);// 这句用接口引用指向,不会报错。如果是实现类强制转换就会抛异常
		return helloProxy;
	}

	public void setAfter(After after) {
		this.after = after;
	}

	public void setBefore(Before before) {
		this.before = before;
	}
}


CGLIB
package proxy.test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 目标对象
 */
class Target {

	public String execute() {
		String message = "----------test()----------";
		System.out.println(message);
		return message;
	}
}

/**
 * 拦截器
 */
class MyMethodInterceptor implements MethodInterceptor {

	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		System.out.println(">>>MethodInterceptor start...");
		Object result = methodProxy.invokeSuper(object, args);
		System.out.println(">>>MethodInterceptor ending...");
		return "here";
	}
}

public class CglibTest {
	public static void main(String rags[]) {
		Target proxyTarget = (Target) createProxy(Target.class);// 强制转换为实现类,不会抛出异常
		String res = proxyTarget.execute();
		System.out.println(res);
	}

	public static Object createProxy(Class targetClass) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(targetClass);
		enhancer.setCallback(new MyMethodInterceptor());
		return enhancer.create();
	}

}

你可能感兴趣的:(java,jdk,AOP,.net)