今天给你们分享的是java设计模式之代理模式中的动态代理模式。若有不足,敬请指正。java
咱们上次说到静态代理使用一个代理类来管理被代理类对象(源对象)的统一处理,代理类必需要继承或者实现一个基类或者接口!!(很笨重)。每一个接口都要实现一个新的代理,每一个方法的逻辑处理,仍是要重复编写。数据库
那么动态代理:就是能够自由的不指定的使用任何接口来实现代理。所谓的动态就不须要指定代理类的固定接口。设计模式
咱们本次用模拟经过代理购买火车票来解释动态代理。ide
图示 |
---|
![]() |
package com.xkt.pojo; import java.util.Date; /** * @author lzx * */ public class Ticket { private int id; private String start; // 发出的 private String destination; // 目的地 private Date startTime; // 出发时间 private float price; // 价格 public Ticket() { super(); // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStart() { return start; } public void setStart(String start) { this.start = start; } public String getDestination() { return destination; } public void setDestination(String destination) { this.destination = destination; } public Date getStartTime() { return startTime; } public void setStartTime(Date startTime) { this.startTime = startTime; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } @Override public String toString() { return "Ticket [id=" + id + ", start=" + start + ", destination=" + destination + ", startTime=" + startTime + ", price=" + price + "]"; } }
package com.xkt.dao; import java.util.Date; import com.xkt.pojo.Ticket; /** * @author lzx * */ public interface TicketDao { /** * 售票的基础dao * * @param start 出发地 * @param destination 目的地 * @param date 出发日期 * @param type 1:火车票 2:机票 * @return */ Ticket getTicket(String start,String destination,Date date); }
package com.xkt.dao.impl; import java.util.Date; import com.xkt.dao.TicketDao; import com.xkt.pojo.Ticket; /** * @author lzx * */ public class TrainTicketDaoImpl implements TicketDao { @Override public Ticket getTicket(String start, String destination, Date date) { Ticket t = new Ticket(); // 模拟查询数据库,获取票信息 t.setId(1); t.setDestination(destination); t.setStart(start); t.setStartTime(date); t.setPrice(300.0f); if ("武汉".equals(start) && "广州".equals(destination)) { t.setPrice(463.0f); } else if ("北京".equals(start) && "广州".equals(destination)) { t.setPrice(885.0f); } else { t.setPrice(500.0f); } System.out.println("---您已购买从 " + start + " 到 " + destination + " 的火车票,请注意发车时间---"); return t; } }
package com.xkt.dao.impl; import java.util.Date; import com.xkt.dao.TicketDao; import com.xkt.pojo.Ticket; /** * @author lzx * */ public class FlightTicketDaoImpl implements TicketDao { @Override public Ticket getTicket(String start, String destination, Date date) { Ticket t = new Ticket(); // 模拟查询数据库,获取票信息 t.setId(1); t.setDestination(destination); t.setStart(start); t.setStartTime(date); t.setPrice(300.0f); if ("武汉".equals(start) && "广州".equals(destination)) { t.setPrice(1000.0f); } else if ("北京".equals(start) && "广州".equals(destination)) { t.setPrice(2000.0f); } else { t.setPrice(500.0f); } System.out.println("---您已购买从 " + start + " 到 " + destination + " 的机票,请注意起飞时间---"); return t; } }
package com.xkt.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Date; import com.xkt.pojo.Ticket; /** * @author lzx * */ public class YellowCrow implements InvocationHandler { // 一、指定代理源(被代理对象) private Object source; // 二、建立代理对象,其实就是黄牛自己 public Object createProxy(Object source) { this.source = source; // 一、拿到接口 Class<?>[] interfaces = source.getClass().getInterfaces(); // 二、拿到classloader ClassLoader classLoader = source.getClass().getClassLoader(); // 三、建立代理对象 Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, this); return proxyInstance; } // args:执行方法过程当中的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String start = (String) args[0]; String destination = (String) args[1]; Date date = (Date) args[2]; // 经过代理,执行真正购票 Ticket invoke = (Ticket) method.invoke(source, args); System.out.println("--黄牛加价100--"); invoke.setPrice(invoke.getPrice() + 100); return invoke; } }
package com.xkt.test; import java.util.Date; import com.xkt.dao.TicketDao; import com.xkt.dao.impl.FlightTicketDaoImpl; import com.xkt.dao.impl.TrainTicketDaoImpl; import com.xkt.pojo.Ticket; import com.xkt.proxy.YellowCrow; /** * @author lzx * */ public class TicketClient { public static void main(String[] args) { // 不经过代理购票,本身在12306上抢 TicketDao tDao = new TrainTicketDaoImpl(); /* * Ticket ticket = tDao.getTicket("武汉", "广州", new Date()); * System.out.println(ticket); */ // 本身购票失败,只能找黄牛 YellowCrow crow = new YellowCrow(); TicketDao tDoProxy = (TicketDao) crow.createProxy(tDao); Ticket ticket2 = tDoProxy.getTicket("武汉", "广州", new Date()); System.out.println(ticket2); testFlight(); } private static void testFlight() { // 一、不经过黄牛,直接去官网购买 TicketDao tDao = new FlightTicketDaoImpl(); /* * Ticket t1 = tDao.getTicket("武汉", "广州", new Date()); System.out.println(t1); */ // 经过黄牛购买 YellowCrow crow = new YellowCrow(); TicketDao createProxy = (TicketDao) crow.createProxy(tDao); Ticket t2 = createProxy.getTicket("武汉", "广州", new Date()); System.out.println(t2); } }
测试结果 |
---|
![]() |
版权说明:欢迎以任何方式进行转载,但请在转载后注明出处!测试