package cn.itcast_05_proxy.service; /** * 这是一个业务的接口,这个接口中的业务就是返回衣服的价格 */ public interface IBoss {//接口 int yifu(String size); }
package cn.itcast_05_proxy.service.impl; import cn.itcast_05_proxy.service.IBoss; /** * 实现了卖衣服的接口 * 自定义了自己的业务,卖裤子 * */ public class Boss implements IBoss{ public int yifu(String size){ //接口的方法 System.err.println("天猫小强旗舰店,老板给客户发快递----衣服型号:"+size); //这件衣服的价钱,从数据库读取 return 50; } public void kuzi(){ //不是接口的方法 System.err.println("天猫小强旗舰店,老板给客户发快递----裤子"); } }
不用代理实现:
package cn.itcast_05_proxy.action; import org.junit.Test; import cn.itcast_05_proxy.service.IBoss; import cn.itcast_05_proxy.service.impl.Boss; public class SaleAction { /** * 不使用代理,直接调用方法 * 方法中规定什么业务,就只能调用什么业务,规定什么返回值,就只能输出什么返回值 */ @Test public void saleByBossSelf() throws Exception { IBoss boss = new Boss(); System.out.println("老板自营!"); int money = boss.yifu("xxl");// 老板自己卖衣服,不需要客服,结果就是没有聊天记录 System.out.println("衣服成交价:" + money); } }
用代理实现:
package cn.itcast_05_proxy.proxyclass; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import cn.itcast_05_proxy.service.IBoss; import cn.itcast_05_proxy.service.impl.Boss; public class ProxyBoss { /** 扩展方法的实现不是加方法。 IBoss boss = ProxyBoss.getProxy(10,IBoss.class,Boss.class), boss就是代理类的实例, int money = boss.yifu("xxl"); */ public static <T> T getProxy(final int discountCoupon,final Class<?> interfaceClass, final Class<?> implementsClass) throws Exception { //这里传的参数类型跟hadoop--19的类型不一样 return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class[] { interfaceClass }, new InvocationHandler() { public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { Integer returnValue = (Integer) method.invoke(implementsClass.newInstance(), args); // 调用原始对象以后返回的值 return returnValue - discountCoupon; } }); } } /* 当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。 Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy: 指代我们所代理的那个真实对象 method: 指代的是我们所要调用真实对象的某个方法的Method对象 args: 指代的是调用真实对象某个方法时接受的参数 Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法, 这个方法的作用就是得到一个动态的代理对象, public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 */
package cn.itcast_05_proxy.action; import org.junit.Test; import cn.itcast_05_proxy.proxyclass.ProxyBoss; import cn.itcast_05_proxy.service.IBoss; import cn.itcast_05_proxy.service.impl.Boss; /** * 什么是动态代理? 简单的写一个模板接口,剩下的个性化工作,好给动态代理来完成! */ public class ProxySaleAction { /** *使用代理,在这个代理中,只代理了Boss的yifu方法 *定制化业务,可以改变原接口的参数、返回值等 */ @Test public void saleByProxy() throws Exception { IBoss boss = ProxyBoss.getProxy(10,IBoss.class,Boss.class);// 将代理的方法实例化成接口 //IBoss boss = new Boss();// 将代理的方法实例化成接口 System.out.println("代理经营!"); int money = boss.yifu("xxl");// 调用接口的方法,实际上调用方式没有变 System.out.println("衣服成交价:" + money); } }