java设计模式之代理模式举例
来源:互联网 发布:晋城网络推广经理招聘 编辑:程序博客网 时间:2024/06/05 16:51
如:有一个添加用户的方法:add(),在添加之前和添加之后要做分别做两中日志记录。
1.静态代理:
1-1.继承的写法:
//接口:package com.watermelon.statics.proxy;public interface UserService { public void add();}
//添加用户的实现类package com.watermelon.statics.proxy;public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("新增add"); }}
//代理类package com.watermelon.statics.proxy;public class UserServiceProxy extends UserServiceImpl{ @Override public void add() { System.out.println("add 之前日志2"); System.out.println("add 之前日志1"); super.add(); System.out.println("add 之后日志1"); System.out.println("add 之后日志2"); }}
//测试方法package com.watermelon.statics.proxy;public class Main { public static void main(String[] args) { UserService userServiceProxy = new UserServiceProxy(); userServiceProxy.add(); }}
//测试结果//add 之前日志2//add 之前日志1//新增add//add 之后日志1//add 之后日志2
缺点:不够灵活,1.每次增加日志需修改代理类。2.若其他方法下需要同样的日志记录,则需要新增代理类。
2-2.聚合的方式:类内部有其他类的变量。
//接口package com.watermelon.statics.proxy;public interface UserService { public void add();}
//实现类package com.watermelon.statics.proxy;public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("新增add"); }}
//代理类1:日志1package com.watermelon.statics.proxy;public class UserServiceProxy2 implements UserService{ private UserService tagert; public UserServiceProxy2(UserService tagert) { super(); this.tagert = tagert; } @Override public void add() { System.out.println("add 之前日志1"); tagert.add(); System.out.println("add 之后日志1"); }}
//代理类2:日志2package com.watermelon.statics.proxy;public class UserServiceProxy3 implements UserService{ private UserService tagert; public UserServiceProxy3(UserService tagert) { super(); this.tagert = tagert; } @Override public void add() { System.out.println("add 之前日志2"); tagert.add(); System.out.println("add 之后日志2"); }}
//测试类package com.watermelon.statics.proxy;public class Main { public static void main(String[] args) { UserService userService = new UserServiceImpl(); UserServiceProxy2 userServiceProxy = new UserServiceProxy2(userService); UserServiceProxy3 userServiceProxy3= new UserServiceProxy3(userServiceProxy); userServiceProxy3.add(); }}
测试结果同上。
和继承的方式比:新增日志记录不用修改代理类源码,直接新增代理类。
缺点:若要给其他的方法新增日志记录,则还是需要新增更多的代理类。
2.jdk动态代理。
//接口package com.watermelon.de.proxy;public interface UserService { public void add();}
//实现类package com.watermelon.de.proxy;public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("新增add"); }}
//代理工厂类 生成代理类 生成日志记录2代理类package com.watermelon.de.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class UserServiceProxyFactory1 implements InvocationHandler{ private Object tagert; public MyTwoInvocationHandeler(Object tagert) { super(); this.tagert = tagert; } public Object getProxy(){ ClassLoader loader = tagert.getClass().getClassLoader(); Class<?>[] interfaces = tagert.getClass().getInterfaces(); return Proxy.newProxyInstance(loader, interfaces, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("之前日志2"); Object result = method.invoke(tagert, args); System.out.println("之后日志2"); return result; }}
//代理工厂类 生成代理类 生成日志记录2代理类package com.watermelon.de.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class UserServiceProxyFactory2 implements InvocationHandler{ private Object tagert; public MyTwoInvocationHandeler(Object tagert) { super(); this.tagert = tagert; } public Object getProxy(){ ClassLoader loader = tagert.getClass().getClassLoader(); Class<?>[] interfaces = tagert.getClass().getInterfaces(); return Proxy.newProxyInstance(loader, interfaces, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("之前日志2"); Object result = method.invoke(tagert, args); System.out.println("之后日志2"); return result; }}
//测试类User类package com.watermelon.de.proxy;public class Main { public static void main(String[] args) { UserService userService = new UserServiceImpl(); //UserServiceProxyFactory1 代理工厂类 UserServiceProxyFactory1 proxyFactory1 = new UserServiceProxyFactory1 (userService); UserService userServiceproxy = (UserService) proxyFactory1.getProxy(); UserServiceProxyFactory2 proxyFactory2 = new UserServiceProxyFactory2(userServiceproxy); UserService userServiceProxy1 = (UserService) proxyFactory2.getProxy(); userServiceProxy1.add(); }}
//测试结果之前日志2之前日志1新增add之后日志1之后日志2
在比如,我现在有个部门类有个update方法也要添加同样的两种日志记录
//部门接口package com.watermelon.de.proxy;public interface DepartmentService { public int update();}
//实现类package com.watermelon.de.proxy;public class DepartmentServiceImpl implements DepartmentService{ @Override public int update() { System.out.println("修改 update"); return 1; }}
//测试类package com.watermelon.de.proxy;public class Main { public static void main(String[] args) { DepartmentService departmentService = new DepartmentServiceImpl(); UserServiceProxyFactory1 proxyFactory1 = new UserServiceProxyFactory1 (departmentService); DepartmentService departmentServiceProxy1 = (DepartmentService) proxyFactory1.getProxy(); UserServiceProxyFactory2 proxyFactory2 = new UserServiceProxyFactory2 (departmentServiceProxy1); DepartmentService departmentServiceProxy2 = (DepartmentService) proxyFactory2.getProxy(); departmentServiceProxy2.update(); }}
结论:使用动态代理每种日志记录可以灵活配置,分开添加。没新增一种日志记录,只需要新增一种代理类的生成类。
生成动态代理类的步骤:
1.添加InvocationHandler接口。实现重写public Object invoke(Object proxy, Method method, Object[] args)
方法。
2.添加一个private Object tagert;
变量、并重写带tagert变量的构造方法。
3.新增一个返回代理类的方法;通过Proxy.newProxyInstance(loader, interfaces, this);
方法返回代理类。
4.cglib动态代理
不用和jdk动态地理一样需要实现同样的接口。直接生成类的动态代理类。
package com.watermelon.cglibproxy;public class UserServiceImpl { public void add() { System.out.println("add loading..."); }}
CglibFactory 代理工厂类
package com.watermelon.cglibproxy;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibFactory implements MethodInterceptor{ private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ //设置创建子类的类 enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** * 拦截所有目标类方法的调用 * obj 目标类的实例 * m 目标方法的反射对象 * args 方法的参数 * proxy代理类的实例 */ @Override public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("日志开始..."); //代理类调用父类的方法 proxy.invokeSuper(obj, args); System.out.println("日志结束..."); return null; }}
测试方法:
public static void main(String[] args) { UserServiceImpl userServiceImpl= new UserServiceImpl(); CglibFactory cglibFactory = new CglibFactory(); UserServiceImpl userServiceImplProxy = (UserServiceImpl)cglibFactory.getProxy(userServiceImpl.getClass()); userServiceImplProxy.add();}
需要引入cglib-nodep-2.2.jar
阅读全文
0 0
- java设计模式之代理模式举例
- java设计模式之代理模式程序举例
- Java设计模式之代理设计模式
- Java设计模式之代理
- Java设计模式之代理
- java设计模式之代理
- java之代理设计模式
- java之代理设计模式
- Java设计模式之代理模式
- Java设计模式之计数代理模式
- JAVA设计模式之代理模式
- JAVA设计模式之代理模式
- java设计模式之代理模式
- Java 设计模式 之 代理模式
- java设计模式之代理模式Proxy
- 设计模式之代理模式 java (1)
- java设计模式之代理模式
- java设计模式之静态代理模式
- Stock Chase--HDOJ
- MySQL常见的查询语句的运用
- 使用安信可ESP8266IDE编辑工具使用最新的乐鑫RTOS固件
- Linux的SOCKET编程详解
- Lua 5.3 源码分析(十)线程的执行与中断
- java设计模式之代理模式举例
- IDEA下创建Web项目
- java服务器对json数据进行gzip压缩
- PIL 库的使用入门
- 静态代理和动态代理
- 理解HTTPS为什么安全前,先看看这些东西
- 数据结构实验之排序四:寻找大富翁
- 前端跨域解决办法(待整理)
- c++中STL库 简介 及 使用说明