基于JDK:
委托类必须实现一个接口,再调用 Proxy.newProxyInstance() 时 ,
JDK会根据InvocationHandler实现类的invoke方法 动态生成一个class字节码文件(这个类会跟委托类实现相同的接口),加载到虚拟机,
基于cglib:
通过继承委托类,重写委托类的方法 实现增强,需要依赖asm包,也是通过动态生成字节码实现;
优劣:
前者要求委托类必须实现接口
后者要求委托类不能为final类
/************************************************************************************/
public class MyProxy2<T> { public <T>T getProxy(Class<?>clazz){ //初始化被代理对象 Object target = clazz.newInstance(); //初始化代理对象的处理逻辑 InvocationHandler handler=new InvocationHandler(){ //obj 表示代理对象,method 被代理对象的方法,args 方法的参数
@Override public Object invoke(Object obj, Method method, Object[] args) throws Throwable { System.out.println(obj.getClass()); Object result=null; try{ //调用target的方法前 result=method.invoke(target, args); //调用target的方法后 }catch(Exception e){ //调用arget的方法发生异常 }finally{ //后置通知 } return result; } }; return (T) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), handler); //根据调用处理者的逻辑生成一个代理对象 } }
public class CglibProxyDemo implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public <T>T getProxy(Class<T> clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return (T) enhancer.create(); } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(method.getName()); System.out.println("后置代理"); Object result = proxy.invokeSuper(obj, args); System.out.println("后置代理"); Matcher matcher = Pattern.compile("^set\w+").matcher(method.getName()); if(matcher.find()){ System.out.println(proxy); return proxy; } return result; } }