java静态代理、java动态代理和cglib代理
静态代理
-
必须有接口或抽象类
-
代理类和被代理的类都需要实现接口或继承抽象类
-
代理类中必须得引用被代理类
-
只能代理指定的类
接口:
package com.peas.proxy.service; public interface IMath { int add(int a, int b); }
实现类:
package com.peas.proxy.service; public class MathImpl implements IMath { @Override public int add(int a, int b) { return a + b; } }
代理类:
package com.peas.proxy.proxy; import com.peas.proxy.service.IMath; import com.peas.proxy.service.MathImpl; public class StaticProxy implements IMath { private MathImpl math; public StaticProxy(MathImpl math) { this.math = math; } @Override public int add(int a, int b) { long begin = System.currentTimeMillis(); int add = this.math.add(a, b); long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - begin) + "毫秒"); return add; } }
测试:
@Test void staticProxy() { StaticProxy proxy = new StaticProxy(new MathImpl()); int add = proxy.add(1, 2); System.out.println("结果是:" + add); }
JDK动态代理
-
JDK动态代理必须是接口,不能是抽象类
-
代理类中必须引用被代理类,以Object接收
-
代理类必须实现InvocationHandler接口,并实现invoke方法,在invoke方法中调用被代理类的方法
-
使用Proxy.newProxyInstence(Loader,Interfaces,Handler)进行调用
接口:
package com.peas.proxy.service; public interface IMath { int add(int a, int b); }
实现类:
package com.peas.proxy.service; public class MathImpl implements IMath { @Override public int add(int a, int b) { return a + b; } }
代理类:
package com.peas.proxy.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxy implements InvocationHandler { private Object proxyObj; public DynamicProxy(Object proxyObj) { this.proxyObj = proxyObj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long begin = System.currentTimeMillis(); Object invoke = method.invoke(this.proxyObj, args); long end = System.currentTimeMillis(); System.out.println("耗时:"+(end - begin) + "毫秒"); return invoke; } public Object incokeProxy(){ return Proxy.newProxyInstance(proxyObj.getClass().getClassLoader(), proxyObj.getClass().getInterfaces(), this); } }
测试:
@Test void dynamicProxy() { DynamicProxy proxy = new DynamicProxy(new MathImpl()); IMath m = (IMath) proxy.incokeProxy(); int add = m.add(1, 2); System.out.println("结果是:" + add); }
CGLib 代理
-
可以对类和接口进行代理,但类不得为final
-
代理类中可以引用被代理类,以Object接收,调用时使用invock()方法,如果不引用,则以invockSuper()方法调用
-
代理类必须实现MethodInterceptor接口,并实现intercept方法,在intercept方法中调用被代理类的方法
-
使用Enhancer创建代理对象
类:
package com.peas.proxy.service; public class MathImpl implements IMath { @Override public int add(int a, int b) { return a + b; } }
代理类:
package com.peas.proxy.proxy; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CGLibProxy implements MethodInterceptor { // private Object relyObj; // // public CGLibProxy(Object relyObj) { // this.relyObj = relyObj; // } @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { long begin = System.currentTimeMillis(); // Object invoke = methodProxy.invoke(this.relyObj); Object invoke = methodProxy.invokeSuper(o); long end = System.currentTimeMillis(); System.out.println("耗时:" + (end - begin) + "毫秒"); return invoke; } public Object getProxyObject(Class clazz) { Enhancer enhancer = new Enhancer(); enhancer.setCallback(this); // enhancer.setSuperclass(this.relyObj); enhancer.setSuperclass(clazz); return enhancer.create(); } }
测试:
@Test void cglibProxy() { CGLibProxy proxy = new CGLibProxy(new MathImpl()); // MathImpl math = (MathImpl) proxy.getProxyObject(); MathImpl math = (MathImpl) proxy.getProxyObject(MathImpl.class); int add = math.add(1, 2); System.out.println("结果是:" + add); }