今天看了某课程的,学习简单的代理应用
首先是不用代理的基本调用
//定义价格接口
public interface IBoss {
//根据衣服尺码,返回衣服的价格 int yifu(String size); }
//价格实现类
public class Boss implements IBoss{ public int yifu(String size){ System.err.println("天猫小强旗舰店,老板给客户发快递----衣服型号:"+size); //生产环境,这件衣服的价钱,从数据库读取 return 50; } }
//业务调用,也就是最基本,接口去new一个实现类。
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); } }
接下来就是改造成代理对象去调用了
代理实现流程:
1、 书写代理类和代理方法,在代理方法中实现代理Proxy.newProxyInstance
2、 代理中需要的参数分别为:被代理的类的类加载器soneObjectclass.getClassLoader(),被代理类的所有实现接口new Class[] { Interface.class },句柄方法new InvocationHandler()
3、 在句柄方法中复写invoke方法,invoke方法的输入有3个参数Object proxy(代理类对象), Method method(被代理类的方法),Object[] args(被代理类方法的传入参数),在这个方法中,我们可以定制化的开发新的业务。
4、 获取代理类,强转成被代理的接口
5、 最后,我们可以像没被代理一样,调用接口的认可方法,方法被调用后,方法名和参数列表将被传入代理类的invoke方法中,进行新业务的逻辑流程。
import reflect.Boss; import reflect.IBoss; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyBoss { public static IBoss getProxyBoss(final int discountCoupon) throws Exception { /** * newProxyInstance,方法有三个参数: * loader: 用哪个类加载器去加载代理对象 * interfaces:动态代理类需要实现的接口 * InvocationHandler:动态代理方法在执行时,会调用h里面的invoke方法去执行 */ Object proxedObj = Proxy.newProxyInstance(Boss.class.getClassLoader(), new Class[] { IBoss.class }, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy方法调用"); System.out.println(method); //这边为啥有个 new Boss()实现类? //因为代理对象不知道要调用哪个-接口-的实现类,所以 //这边指定IBoss接口-代理实现-Boss实现类 Integer returnValue = (Integer) method.invoke(new Boss(), args);// 调用原始对象以后返回的值 return returnValue - discountCoupon; } } ); return (IBoss)proxedObj; } }
//代理业务调用
public class ProxySaleAction { @Test public void saleByProxy() throws Exception { IBoss boss = ProxyBoss.getProxyBoss(20);// 将代理的方法实例化成接口 System.out.println("代理经营!"); int money = boss.yifu("xxl");// 调用接口的方法,实际上调用方式没有变 // System.out.println("衣服成交价:" + money); } }