看本篇博文之前,请先了解代理模式。了解代理模式请点这里
JDK动态代理
JDK的动态代理,是由JDK的java.lang.reflect.*包提供支持的,我们需要完成这么几个步骤。
.编写服务类和接口,这个是真正的服务提供者,在JDK代理接口是必须的。
.编写代理类,提供绑定和代理方法。
JDK动态代理最大的缺点就是需要提供接口
直接看例子:
接口类:HelloService:
public interface HelloService { public void sayHello(String name); }
实现类:HelloServiceImpl
public class HelloServiceImpl implements HelloService { @Override public void sayHello(String name) { System.out.println("hello " + name); } }
代理类:HelloServiceProxy
public class HelloServiceProxy implements InvocationHandler { /*真实服务对象*/ private Object target; public Object bind(Object target){ this.target = target; /*JDK生成一个代理对象,有三个参数, 第一个是类加载器:target.getClass().getClassLoader() 第二个是接口:target.getClass().getInterfaces() 第三个是代表当前类:this*/ Object object = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); return object; } /** * * @param proxy 代理对象 * @param method 当前调用的的那个方法 * @param args 方法参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我的JDK动态代理"); Object result = null; System.out.println("我准备说hello"); /*调用方法*/ result = method.invoke(target,args); System.out.println("我说过hello了"); return result; } }
测试类:HelloServiceMain
public class HelloServiceMain { public static void main(String[] args) { /*创建代理对象*/ HelloServiceProxy helloServiceProxy = new HelloServiceProxy(); /*根据代理对象创建实际对象*/ HelloService proxy =(HelloService)helloServiceProxy.bind(new HelloServiceImpl()); proxy.sayHello("张三"); } }控制台输出结果:
我的JDK动态代理 我准备说hello hello 张三 我说过hello了
我们在代理对象HelloServiceProxy中创建了真实对象target,并实现了InvocationHandler接口,实现invoke()方法,并提供一个bind()方法,让我们把真实对象传进来。随后,我们在测试类调用的时候,先创建了代理对象,调用了代理对象的bind()方法,并传入真实对象的,即HelloService,这时,代理对象代理的就是HelloService,当我们调用sayHello()方法时,代理对象会先运行自己的invoke()方法,并通过自己的底层封装的类获得我们调用的是sayHello(),参数是“张三”,然后在invoke()方法里用真实对象调用sqHello()方法,并传入参数“张三”。
CGLIB动态代理
扫描二维码关注公众号,回复:
1722859 查看本文章
该代理不需要接口,只需要实现类,即可。
还是上诉的例子,只是代理类变一下
代理类:HelloServiceCglib:
public class HelloServiceCgLib implements MethodInterceptor{ /*真实对象*/ private Object target; public Object getInstance(Object target){ this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); /*回调方法*/ enhancer.setCallback(this); /*创建代理对象*/ return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("我的CGLIB的动态代理"); System.out.println("我准备说hello"); Object returnObj = methodProxy.invokeSuper(o,objects); System.out.println("我说过hello了"); return returnObj; } }运行实现类:HelloServiceMain:
public class HelloServiceMain { @Test public void cglibTest(){ HelloServiceCgLib cgLib = new HelloServiceCgLib(); HelloServiceImpl service =(HelloServiceImpl)cgLib.getInstance(new HelloServiceImpl()); service.sayHello("张三"); } }运行结果:
我的CGLIB的动态代理 我准备说hello hello 张三 我说过hello了CGLIB为我们的实现类提供了一个子类,并在子类中采用拦截技术拦截父类的调用,从而达到代理的作用。