JDK代理和CGLIB代理

java代理模式

java可以分为JDK动态代理和CGLIB代理。JDK动态代理只能对实现了接口的类生成代理,而不能针对类。CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。
CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些

JDK动态代理

package hong_liang.base;

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

public class MyProxy {
	public interface IHello {
		void sayHello();
	}
	
	static void hello(String str){
		System.out.println("111");
	}

	static class Hello implements IHello {
		public void sayHello() {
			System.out.println("Hello world!!");
		}
	}

	// 自定义InvocationHandler
	static class HWInvocationHandler implements InvocationHandler {
		// 目标对象
		private Object target;

		public HWInvocationHandler(Object target) {
			this.target = target;
		}

		public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
			System.out.println("------插入前置通知代码-------------");
			// 执行相应的目标方法
			Object rs = method.invoke(target, args);
			System.out.println("------插入后置处理代码-------------");
			return rs;
		}
	}

	public static void main(String[] args) throws Exception {
		// 生成$Proxy0的class文件
		System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
		// 获取动态代理类
		Class<?> proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(),IHello.class);
		// 获得代理类的构造函数,并传入参数类型InvocationHandler.class
		Constructor<?> constructor = proxyClazz.getConstructor(InvocationHandler.class);
		// 通过构造函数来创建动态代理对象,将自定义的InvocationHandler实例传入
		IHello iHello = (IHello) constructor.newInstance(new HWInvocationHandler(new Hello()));
		// 通过代理对象调用目标方法
		iHello.sayHello();
		
		//第二种方式动态调用
		IHello iHello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(),new Class[]{IHello.class}, new HWInvocationHandler(new Hello()));
		iHello2.sayHello();
	}
	
}

CGLIB动态代理

package sunhongliang;

import java.lang.reflect.Method;

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

public class CglibTest {
	public static void main(String[] args) {
		CglibTs ct = new CglibTs();
		ClassHasNoInterface chni = (ClassHasNoInterface) ct.getProxy(ClassHasNoInterface.class);
		chni.method();
		chni.function();
	}
}

class ClassHasNoInterface {

	public void method() {
		System.out.println("建立自己的知识体系还是很重要的,尽管觉得麻烦");
	}

	public void function() {
		System.out.println("如果我只停留在使用的别人开发的工具阶段,那么再过5年我也对不起程序员这个称呼");
	}
}

class CglibTs implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();

	public Object getProxy(Class<?> clazz) {
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}

	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		System.out.println(method.getName() + "执行之前做一些准备工作");
		// 一不小心写成下面被注释一行代码了。 StackOverflowError
		// Object result = method.invoke(obj, args);
		Object result = proxy.invokeSuper(obj, args);
		System.out.println(method.getName() + "执行之后做一些准备的工作");
		return result;
	}
}

转载于:https://my.oschina.net/hongliangsun/blog/1587837

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值