一、Cglib
CGLIB 呢, 相对于Java的代理来说, 更加灵活和富有弹性, 他的功能提供的更加的强大, 依靠callback实现的功能的增强.
通过这篇文章我相信你对于CGLIB的了解会提升一个档次的 . 本文开始从快速开始上手体验, 理解其核心模块,到源码分析其启动流程, 然后分析一些存在的问题.
官网地址: https://github.com/cglib/cglib
Demo
被增强的类
1 2 3 4 5 6 7 8 9 10
| public class UserServiceImp { public String getName(int id){ System.out.println("getName()"+id); return "Tom"; } public int getAge(int id){ System.out.println("getAge()"+id); return 10; } }
|
增强
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class App { public static void main(String[] args) { System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/test"); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(UserServiceImp.class); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return "proxy" + proxy.invokeSuper(obj, args); } }); UserServiceImp userService1=(UserServiceImp) enhancer.create(); userService1.getName(1); userService1.getAge(1); } }
|
二、Jdk动态代理
JDK动态代理基于拦截器和反射来实现。
JDK代理是不需要第三方库支持的,只需要JDK环境就可以进行代理,使用条件:
1)必须实现InvocationHandler接口;
2)使用Proxy.newProxyInstance产生代理对象;
3)被代理的对象必须要实现接口;
Demo
1.接口
1 2 3
| public interface IHello { void sayHello(); }
|
2.实现类
1 2 3 4 5 6
| public class HelloImpl implements IHello { @Override public void sayHello() { System.out.println("Hello world!"); } }
|
3. InvocationHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class JdkInvocationHandler implements InvocationHandler { private Object target; public JdkInvocationHandler(Object target){ this.target = target; } @Override 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; } }
|
4.Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy;
public class JdkProxyTest { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); Class proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(),IHello.class); Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class); IHello iHello1 = (IHello) constructor.newInstance(new JdkInvocationHandler(new HelloImpl())); iHello1.sayHello();
IHello iHello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), new Class[]{IHello.class}, new JdkInvocationHandler(new HelloImpl())); iHello2.sayHello(); } }
|