标签:
动态代理:
在程序运行时,运用反射机制动态创建代理类,不需要程序员编写源代码.动态代理简化了编程工作,提高了系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类.说到底,java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力.
具体说来,JDK动态代理中包含一个Proxy类和一个InvocationHandler接口.
public staticObject newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException{}
publicinterface InvocationHandler {
publicObject invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
注意:以上说的是JDK的动态代理,JDK动态代理最大的缺点就是依靠接口实现,如果一些类没有接口,JDK动态代理就无能为力了。
面对JDK动态缺点,CGLib又发挥了它的怎样优势呢?
CGLib动态代理包含MethodProxy、Proxy类和一个接口MethodInterceptor
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}public interface MethodInterceptor extends Callback
{
public Object intercept(Object obj, java.lang.reflect.Method method,Object[] args,MethodProxy proxy) throws Throwable;
}CGLib动态代理Demo:
没有实现接口的实现类:
//没有实现接口的打招呼类
public class greetingimpl {
public void sayhello(String name) {
System.out.println(name+" sayhello");
}
}
CGLib动态代理类:
//CGLib动态代理类
public class CGLibDynamicProxy implements MethodInterceptor{
//单例模式创建代理对象
private static CGLibDynamicProxy instance=new CGLibDynamicProxy();
//空的构造方法
private CGLibDynamicProxy(){
}
//返回代理对象的实例
public static CGLibDynamicProxy getInstance(){
return instance;
}
//获得被代理的对象
public <T> T getProxy(Class<T> cls){
return (T) Enhancer.create(cls, this);
}
//拦截被代理对象的方法,在前后分别执行before()和after()方法
@Override
public Object intercept(Object target, Method method, Object[] args,MethodProxy proxy) throws Throwable {
before();
//Object result=proxy.invokeSuper(target, args);//方式一:这是CGLib动态代理比JDK动态代理方式多出来的方法,效率更高
//Object result=proxy.invoke(target, args);//方式二:使用该方法报"栈溢出"错:Exception in thread "main" java.lang.StackOverflowError
Object result=method.invoke(target, args);//方式三:这是JDK动态代理中使用的方式
after();
return result;
}
//在代理类的方法的方法前执行
public void before(){
System.out.println("Before");
}
//在代理类的方法的方法后执行
public void after(){
System.out.println("After");
}
}Client类:
public class client {
public static void main(String[] args) {
greetingimpl greetingimpl=CGLibDynamicProxy.getInstance().getProxy(greetingimpl.class);
greetingimpl.sayhello("CGLibDynamicProxy");
}
}打印结果:
有接口的实现类:
//实现接口的打招呼类
public class greetingimpl implements greeting{
public void sayhello(String name) {
System.out.println(name+" sayhello");
}
}
Client类:
public class client {
public static void main(String[] args) {
greeting greeting=CGLibDynamicProxy.getInstance().getProxy(greetingimpl.class);
greeting.sayhello("CGLibDynamicProxy");
}
}
使用相同的CGLib动态代理类
打印结果:
总结:
CGLib动态代理在JDK动态代理的的基础上了做了解决了没有实现接口类的动态代理问题,其关键点体现在动态代理类所提供的方法的能力上稍做了些增强,可以说CGLib动态代理就是JDK动态代理的改进版。
标签:
原文地址:http://blog.csdn.net/wang13667539325/article/details/46623787