思考一下,如果要在Java Web项目中完成两个功能:
1、打印每个请求从开始到结束的耗时
2、校验某些请求的当前用户是否登录
按照常规思路,解决办法就是
1、在每个请求的 controller 代码的开始和结尾都记录时间,最后打印一下这个时间差
2、在每个需要校验的请求代码中,加上校验当前用户是否登录的代码
这样:
修改了原来的代码逻辑每个涉及的点都需要改动,改动量很大有没有办法就处理这种统一的需求,而不改动原来代码,让原来的代码仍然只关心最核心的业务逻辑?
有,使用代理模式。让代理者去处理统一的需求,被代理者只需实现最核心的业务逻辑。
模拟原始的业务代码:
package constxiong.cxproxy.chapter1; import constxiong.cxproxy.chapter1.service.Service; import constxiong.cxproxy.chapter1.service.ServiceImpl; /** * 测试类 * @author ConstXiong * @date 2019-05-29 11:01:30 */ public class Test { public static void main(String[] args) { Service service = new ServiceImpl(); service.login("ConstXiong", "123456"); service.getUserInfo("ConstXiong"); } } package constxiong.cxproxy.chapter1.service; import java.util.Map; /** * 服务接口 * @author ConstXiong * @date 2019-05-29 11:02:02 */ public interface Service { boolean login(String username, String password); Map<String, Object> getUserInfo(String username); } package constxiong.cxproxy.chapter1.service; import java.util.HashMap; import java.util.Map; /** * 服务接口实现 * @author ConstXiong * @date 2019-05-29 11:02:15 */ public class ServiceImpl implements Service { @Override public boolean login(String username, String password) { simulateDaOperation(100); System.out.println("用户名:" + username + ", 密码:" + password + " 登录成功"); return true; } @Override public Map<String, Object> getUserInfo(String username) { Map<String, Object> userInfo = new HashMap<String, Object>(); simulateDaOperation(100); userInfo.put("username", username); userInfo.put("sex", "男"); userInfo.put("age", 18); System.out.println("用户名:" + username + ", 获取用户信息:" + userInfo); return userInfo; } /** * 模拟数据库操作,休眠 * @param millis 毫秒数 */ private void simulateDaOperation(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { e.printStackTrace(); } } }测试类执行结果:
用户名:ConstXiong, 密码:123456 登录成功 用户名:ConstXiong, 获取用户信息:{sex=男, age=18, username=ConstXiong}
下面我们不使用代理,完成功能。

