1 jdk实现动态代理源码实现
这里需要用到InvocationHandler接口
public interface Hello { public void sayHello(); }
public class HelloImpl implements Hello { @Override public void sayHello() { System.out.println("hello word"); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class HelloInvocationHandler implements InvocationHandler{ private Object object; PeopleInvocationHandler(Object object){ this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-------- start ---------"); Object invoke = method.invoke(people, args); System.out.println("-------- end ---------"); return invoke; } }
import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { HelloImpl hello = new HelloImpl(); HelloInvocationHandler invocationHandler = new HelloInvocationHandler(hello); Hello proxy = (Hello) Proxy.newProxyInstance(HelloImpl.getClass().getClassLoader(), HelloImpl.getClass().getInterfaces(), invocationHandler); proxy.sayHello(); } }
2 CGLib实现动态代理源码实现
这里需要用到MethodInterceptor接口和Enhancer
public class Hello { public Hello() { System.out.println("Hello..."); } public void print() { System.out.println("hello word"); } }
public class CglibProxyIntercepter implements MethodInterceptor { @Override public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //对目标方法进行拦截处理 System.out.println("before..."); Object object = methodProxy.invokeSuper(sub, objects); System.out.println("after..."); return object; } }
public class CglibProxyIntercepter implements MethodInterceptor { @Override public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //对目标方法进行拦截处理 System.out.println("before..."); Object object = methodProxy.invokeSuper(sub, objects); System.out.println("after..."); return object; } }
public class Test { public static void main(String[] args) { //创建加强器,用来创建动态代理类 Enhancer enhancer = new Enhancer(); //为加强器指定要代理的业务类 enhancer.setSuperclass(Hello.class); //设置回调 enhancer.setCallback(new CglibProxyIntercepter()); //创建代理对象 Hello proxy= (Hello) enhancer.create(); proxy.print(); } }
result
before... hello word after...
3 对比jdk实现动态代理CGLib实现动态代理
1)、JDK
内部主要是通过反射来实现。
2)、CGLib
CGLib是依靠asm字节码处理框架实现的高性能Code生成类库,可以在运行时扩展Java类或者实现接口?当然可以,CGLib对用户隐藏了asm复杂的内部实现,提供了Developer友好、面向特定功能的实现,比如方法拦截(Interpreter)、懒加载(Lazyloader & Dispatcher)等,AOP中的方法拦截,Hibernate中的延迟加载都利用了CGLib
特点:可以不通过接口实现动态代理的优点之外,还有处理速度快、效率高的优点!因为生成代码比Java反射的速度要快很多.