设计模式:动态代理与静态代理

妖狐艹你老母 2022-05-24 04:15 320阅读 0赞

动态代理与静态代理

什么是代理模式

代理模式即一个类(代理类)具有另一个类(被代理类)的所有行为。代理类可以在不更改业务逻辑的情况下扩展被代理类的方法,达到让被代理类更加专注的去处理本身所具有的业务逻辑。
代理模式包括动态代理和静态代理。
静态代理是指在程序运行之前已经存在的代理类及代理实现,即开发者需要在程序运行之前就写好代理类及代理实现。动态代理是指程序运行之后,根据业务逻辑需求,动态的获取、创建被代理类的功能。可以采用JDK、CGLIB来实现动态代理。

静态代理编码实现

创建被代理类接口

  1. package cn.tyrone.java.designpattern.staticproxy;
  2. /** * 电脑厂商接口 * @author shanglishuai * */
  3. public interface IPCBrand {
  4. /** * 生产电脑 * @param pcModel 电脑型号 */
  5. public void makePC(String pcModel);
  6. /** * 出售电脑 * @param pcModel 电脑型号 */
  7. public void sellPC(String pcModel);
  8. }

创建被代理类

  1. package cn.tyrone.java.designpattern.staticproxy;
  2. /** * 联想电脑厂商 * @author shanglishuai * */
  3. public class LenevoPCBrand implements IPCBrand {
  4. @Override
  5. public void makePC(String pcModel) {
  6. System.out.println("新研发的的电脑型号:" + pcModel);
  7. }
  8. @Override
  9. public void sellPC(String pcModel) {
  10. System.out.println("出售最新的电脑型号:" + pcModel);
  11. }
  12. }

创建代理类

  1. package cn.tyrone.java.designpattern.staticproxy;
  2. /** * 联想电脑厂商代理商 * @author shanglishuai * */
  3. public class LenevoPCBrandProxy implements IPCBrand {
  4. //
  5. private IPCBrand pcBrand;
  6. public LenevoPCBrandProxy(IPCBrand pcBrand) {
  7. this.pcBrand = pcBrand;
  8. }
  9. /** * 代理联想电脑厂商生产电脑 */
  10. @Override
  11. public void makePC(String pcModel) {
  12. System.out.println("我是联想电脑厂商的代理商");
  13. pcBrand.makePC(pcModel);
  14. }
  15. /** * 代理联想电脑厂商出售电脑 */
  16. @Override
  17. public void sellPC(String pcModel) {
  18. System.out.println("我是联想电脑厂商的代理商");
  19. pcBrand.sellPC(pcModel);
  20. }
  21. }

测试类

  1. package cn.tyrone.java.designpattern.staticproxy;
  2. /** * 静态代理测试 * * @author shanglishuai * */
  3. public class StaticProxyTest {
  4. public static void main(String[] args) {
  5. IPCBrand lenevoPCBrand = new LenevoPCBrand();
  6. IPCBrand lenevoPCBrandProxy = new LenevoPCBrandProxy(lenevoPCBrand);
  7. String pcModel = "G470-New";
  8. lenevoPCBrand.makePC(pcModel);
  9. lenevoPCBrand.makePC(pcModel);
  10. System.out.println("\n");
  11. lenevoPCBrandProxy.makePC(pcModel);
  12. lenevoPCBrandProxy.makePC(pcModel);
  13. }
  14. }

JDK方式实现动态代理

创建被代理类接口

  1. package cn.tyrone.java.designpattern.dynamicproxy.jdk;
  2. /** * 电脑厂商接口 * @author shanglishuai * */
  3. public interface IPCBrand {
  4. /** * 生产电脑 * @param pcModel 电脑型号 */
  5. public void makePC(String pcModel);
  6. /** * 出售电脑 * @param pcModel 电脑型号 */
  7. public void sellPC(String pcModel);
  8. }

创建被代理类

  1. package cn.tyrone.java.designpattern.dynamicproxy.jdk;
  2. /** * 联想电脑厂商 * @author shanglishuai * */
  3. public class LenevoPCBrand implements IPCBrand {
  4. @Override
  5. public void makePC(String pcModel) {
  6. System.out.println("新研发的的电脑型号:" + pcModel);
  7. }
  8. @Override
  9. public void sellPC(String pcModel) {
  10. System.out.println("出售最新的电脑型号:" + pcModel);
  11. }
  12. }

创建JDK动态代理类
JDK动态代理需要实现InvocationHandler接口来实现

  1. package cn.tyrone.java.designpattern.dynamicproxy.jdk;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. /** * 使用jdk实现动态代理方法 * @author shanglishuai * */
  6. public class JDKProxy implements InvocationHandler {
  7. // 真实对象
  8. private Object target = null;
  9. /** * 建立代理对象与真实对象的代理关系,并返回代理对象 * @param target 真实对象 * @return 代理对象 */
  10. public Object bind(Object target) {
  11. this.target = target;
  12. return Proxy.newProxyInstance(target.getClass().getClassLoader(),
  13. target.getClass().getInterfaces(), this);
  14. }
  15. /** * 代理方法逻辑 * @param proxy 代理对象 * @param method 当前调度方法 * @param args 当前方法参数 * @return 代理结果返回 * @throws Throwable 异常 */
  16. @Override
  17. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  18. System.out.println("调用真实对象的业务方法之前的业务逻辑");
  19. Object obj = method.invoke(target, args); // 调用真实对象的业务处理方法
  20. System.out.println("调用真实对象的业务方法之后的业务逻辑");
  21. System.out.println("\n");
  22. return obj;
  23. }
  24. }

JDK动态代理测试类

  1. package cn.tyrone.java.designpattern.dynamicproxy.jdk;
  2. public class JDKProxyTest {
  3. public static void main(String[] args) {
  4. IPCBrand pcBrand = new LenevoPCBrand();
  5. JDKProxy jdkProxy = new JDKProxy();
  6. // 绑定真实对象
  7. IPCBrand pcBrandProxy = (IPCBrand)jdkProxy.bind(pcBrand);
  8. String pcModel = "G470-New";
  9. pcBrandProxy.makePC(pcModel);
  10. pcBrandProxy.sellPC(pcModel);
  11. }
  12. }

采用CGLIB实现动态代理

创建被代理类

  1. package cn.tyrone.java.designpattern.dynamicproxy.cglib;
  2. /** * 联想电脑厂商 * @author shanglishuai * */
  3. public class LenevoPCBrand {
  4. public void makePC(String pcModel) {
  5. System.out.println("新研发的的电脑型号:" + pcModel);
  6. }
  7. public void sellPC(String pcModel) {
  8. System.out.println("出售最新的电脑型号:" + pcModel);
  9. }
  10. }

创建CGLIB动态代理类

  1. package cn.tyrone.java.designpattern.dynamicproxy.cglib;
  2. import java.lang.reflect.Method;
  3. import net.sf.cglib.proxy.Enhancer;
  4. import net.sf.cglib.proxy.MethodInterceptor;
  5. import net.sf.cglib.proxy.MethodProxy;
  6. /** * Cglib实现动态代理 * 使用Cglib实现动态代理需要实现MethodInterceptor接口 * @author shanglishuai * */
  7. public class CglibProxy implements MethodInterceptor {
  8. /** * 生成Cglib代理对象 * @param cls 代理类 * @return 代理类的代理对象 */
  9. public Object getProxy(Class cls) {
  10. // Cglib enhancer 增加类对象
  11. Enhancer enhancer = new Enhancer();
  12. // 设置增强类型
  13. enhancer.setSuperclass(cls);
  14. // 定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor接口
  15. enhancer.setCallback(this);
  16. // 创建并返回代理对象
  17. return enhancer.create();
  18. }
  19. /** * @param proxy 代理对象 * @param method 方法 * @param args 方法参数 * @param methodProxy 方法代理 * @return result 代理逻辑返回 * @throws Throwable 异常 */
  20. @Override
  21. public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  22. System.out.println("执行真实对象方法之前可以添加的业务逻辑");
  23. Object result = methodProxy.invokeSuper(proxy, args);
  24. System.out.println("执行真实对象方法之后可以添加的业务逻辑\n");
  25. return result;
  26. }
  27. }

创建CGLIB动态代理测试类

  1. package cn.tyrone.java.designpattern.dynamicproxy.cglib;
  2. public class CglibProxyTest {
  3. public static void main(String[] args) {
  4. CglibProxy cglibProxy = new CglibProxy();
  5. LenevoPCBrand lenevoPCBrandProxy = (LenevoPCBrand)cglibProxy.getProxy(LenevoPCBrand.class);
  6. String pcModel = "G470-New";
  7. lenevoPCBrandProxy.makePC(pcModel);
  8. lenevoPCBrandProxy.sellPC(pcModel);
  9. }
  10. }

发表评论

表情:
评论列表 (有 0 条评论,320人围观)

还没有评论,来说两句吧...

相关阅读