当前位置:首页 > CN2资讯 > 正文内容

java代理服务器搭建 java编写代理服务

9小时前CN2资讯



JAVA的动态代理 

代理模式 

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 

按照代理的创建时期,代理类可以分为两种。 

静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 

动态代理:在程序运行时,运用反射机制动态创建而成。 

 

首先看一下静态代理: 

1、Count.java 

Java代码 

1. package net.battier.dao; 2. 3. /** 4. * 定义一个账户接口 5. * 6. * @author Administrator 7. * 8. */ 9. public interface Count { 10. // 查看账户方法 11. public void queryCount(); 12. 13. // 修改账户方法 14. public void updateCount(); 15. 16. }

 

2、CountImpl.java 

Java代码 

1. package net.battier.dao.impl; 2. 3. import net.battier.dao.Count; 4. 5. /** 6. * 委托类(包含业务逻辑) 7. * 8. * @author Administrator 9. * 10. */ 11. public class CountImpl implements Count { 12. 13. @Override 14. public void queryCount() { 15. System.out.println("查看账户方法..."); 16. 17. } 18. 19. @Override 20. public void updateCount() { 21. System.out.println("修改账户方法..."); 22. 23. } 24. 25. } 26. 27. 、CountProxy.java 28. package net.battier.dao.impl; 29. 30. import net.battier.dao.Count; 31. 32. /** 33. * 这是一个代理类(增强CountImpl实现类) 34. * 35. * @author Administrator 36. * 37. */ 38. public class CountProxy implements Count { 39. private CountImpl countImpl; 40. 41. /** 42. * 覆盖默认构造器 43. * 44. * @param countImpl 45. */ 46. public CountProxy(CountImpl countImpl) { 47. this.countImpl = countImpl; 48. } 49. 50. @Override 51. public void queryCount() { 52. System.out.println("事务处理之前"); 53. // 调用委托类的方法; 54. countImpl.queryCount(); 55. System.out.println("事务处理之后"); 56. } 57. 58. @Override 59. public void updateCount() { 60. System.out.println("事务处理之前"); 61. // 调用委托类的方法; 62. countImpl.updateCount(); 63. System.out.println("事务处理之后"); 64. 65. } 66. 67. }

 

3、TestCount.java 

Java代码 

1. package net.battier.test; 2. 3. import net.battier.dao.impl.CountImpl; 4. import net.battier.dao.impl.CountProxy; 5. 6. /** 7. *测试Count类 8. * 9. * @author Administrator 10. * 11. */ 12. public class TestCount { 13. public static void main(String[] args) { 14. CountImpl countImpl = new CountImpl(); 15. CountProxy countProxy = new CountProxy(countImpl); 16. countProxy.updateCount(); 17. countProxy.queryCount(); 18. 19. } 20. }

 

观察代码可以发现每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。 

再来看一下动态代理: 

JDK动态代理中包含一个类和一个接口: 

InvocationHandler接口: 

public interfaceInvocationHandler { public Objectinvoke(Object proxy,Method method,Object[] args) throws Throwable; }

参数说明: 

Objectproxy:指被代理的对象。 

Methodmethod:要调用的方法 

Object[]args:方法调用时所需要的参数 

可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。 

Proxy类: 

Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法: 

public static ObjectnewProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandlerh) throws IllegalArgumentException

参数说明: 

ClassLoaderloader:类加载器 

Class<?>[]interfaces:得到全部的接口 

InvocationHandlerh:得到InvocationHandler接口的子类实例 

Ps:类加载器 

在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器; 

BooststrapClassLoader:此加载器采用C++编写,一般开发中是看不到的; 

ExtendsionClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类; 

AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。 

动态代理 

与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类。java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。 

动态代理示例: 

1、BookFacade.java Java代码 1. package net.battier.dao; 2. 3. public interface BookFacade { 4. public void addBook(); 5. }

 

2、BookFacadeImpl.java 

Java代码 

1. package net.battier.dao.impl; 2. 3. import net.battier.dao.BookFacade; 4. 5. public class BookFacadeImpl implements BookFacade { 6. 7. @Override 8. public void addBook() { 9. System.out.println("增加图书方法。。。"); 10. } 11. 12. } 13. 14. 、BookFacadeProxy.java 15. 16. package net.battier.proxy; 17. 18. import java.lang.reflect.InvocationHandler; 19. import java.lang.reflect.Method; 20. import java.lang.reflect.Proxy; 21. 22. /** 23. * JDK动态代理代理类 24. * 25. * @author student 26. * 27. */ 28. public class BookFacadeProxy implements InvocationHandler { 29. private Object target; 30. /** 31. * 绑定委托对象并返回一个代理类 32. * @param target 33. * @return 34. */ 35. public Object bind(Object target) { 36. this.target = target; 37. //取得代理对象 38. return Proxy.newProxyInstance(target.getClass().getClassLoader(), 39. target.getClass().getInterfaces(), this); //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷) 40. } 41. 42. @Override 43. /** 44. * 调用方法 45. */ 46. public Object invoke(Object proxy, Method method, Object[] args) 47. throws Throwable { 48. Object result=null; 49. System.out.println("事物开始"); 50. //执行方法 51. result=method.invoke(target, args); 52. System.out.println("事物结束"); 53. return result; 54. } 55. 56. }

 

3、TestProxy.java 

Java代码

1. package net.battier.test; 2. 3. import net.battier.dao.BookFacade; 4. import net.battier.dao.impl.BookFacadeImpl; 5. import net.battier.proxy.BookFacadeProxy; 6. 7. public class TestProxy { 8. 9. public static void main(String[] args) { 10. BookFacadeProxy proxy = new BookFacadeProxy(); 11. BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl()); 12. bookProxy.addBook(); 13. } 14. 15. }

 

但是,JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。 

Cglib动态代理 

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。 

示例 

1、BookFacadeCglib.java 

Java代码 

1. package net.battier.dao; 2. 3. public interface BookFacade { 4. public void addBook(); 5. }

 

2、BookCadeImpl1.java 

Java代码 

1. package net.battier.dao.impl; 2. 3. /** 4. * 这个是没有实现接口的实现类 5. * 6. * @author student 7. * 8. */ 9. public class BookFacadeImpl1 { 10. public void addBook() { 11. System.out.println("增加图书的普通方法..."); 12. } 13. }

 

3、BookFacadeProxy.java 

Java代码

1. package net.battier.proxy; 2. 3. import java.lang.reflect.Method; 4. 5. import net.sf.cglib.proxy.Enhancer; 6. import net.sf.cglib.proxy.MethodInterceptor; 7. import net.sf.cglib.proxy.MethodProxy; 8. 9. /** 10. * 使用cglib动态代理 11. * 12. * @author student 13. * 14. */ 15. public class BookFacadeCglib implements MethodInterceptor { 16. private Object target; 17. 18. /** 19. * 创建代理对象 20. * 21. * @param target 22. * @return 23. */ 24. public Object getInstance(Object target) { 25. this.target = target; 26. Enhancer enhancer = new Enhancer(); 27. enhancer.setSuperclass(this.target.getClass()); 28. // 回调方法 29. enhancer.setCallback(this); 30. // 创建代理对象 31. return enhancer.create(); 32. } 33. 34. @Override 35. // 回调方法 36. public Object intercept(Object obj, Method method, Object[] args, 37. MethodProxy proxy) throws Throwable { 38. System.out.println("事物开始"); 39. proxy.invokeSuper(obj, args); 40. System.out.println("事物结束"); 41. return null; 42. 43. 44. } 45. 46. }

 

4、TestCglib.java 

Java代码 

1. package net.battier.test; 2. 3. import net.battier.dao.impl.BookFacadeImpl1; 4. import net.battier.proxy.BookFacadeCglib; 5. 6. public class TestCglib { 7. 8. public static void main(String[] args) { 9. BookFacadeCglib cglib=new BookFacadeCglib(); 10. BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1()); 11. bookCglib.addBook(); 12. } 13. }

 


    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/25044.html

    分享给朋友:

    “java代理服务器搭建 java编写代理服务” 的相关文章

    获取最佳VPS优惠码的终极指南

    VPS优惠概述 在当今数字化时代,虚拟专用服务器(VPS)成为许多人理想的选择。VPS是一种能提供比共享主机更高性能、更多自主控制权的网络托管方式。对于个人和企业用户来说,使用VPS无疑能提升网站的加载速度以及平台的稳定性。它的高级配置和灵活性,为用户在资源管理上提供了极大的便利。 VPS的优势体现...

    全球主机论坛:交流与学习的技术社区

    在现代社会,全球主机论坛的出现为我们提供了一个交流和学习的平台。这个论坛主要聚焦于主机领域,用户可以自由讨论主机的各种话题,分享个人经验,并获取最新的行业信息。对我而言,这样的论坛不仅是一个获取知识的地方,更是一个与全球主机用户互动的社区。 全球主机论坛的重要性毋庸置疑。它为主机使用者提供了一个集中...

    UCloud优:云计算服务平台的领先者与优势分析

    UCloud优的基本介绍 谈到UCloud,首先让我想起它成立的背景以及它是如何从一颗种子成长为今天的云计算巨头。UCloud,或者说优刻得科技股份有限公司,于当时顺应了数字化转型的浪潮。这是一个中立、安全的云计算服务平台,专注于为各行各业提供云服务。它的创立背景与各种市场需求紧密相连,尤其是企业对...

    全面指南:在Linux上使用dd命令安装Windows系统的教程

    在当今的技术环境中,许多用户都希望能够在Linux系统上安装Windows。这不仅能帮助开发者和测试人员多平台间的快速切换,还能让个人用户享受到两个操作系统的优点。dd命令成为了实现这一目标的一个重要工具,通过它,可以将Windows操作系统的映像文件直接写入到一个虚拟专用服务器上。这篇教程将为你提...

    如何选择高性能、美西VPS服务商: 比较、评测及优化建议

    美西VPS概述 美西VPS,简单来说,就是那些位于美国西部地区的虚拟专用服务器,像在洛杉矶这样的城市里。这些服务器给用户提供了一种灵活而高效的托管解决方案,特别是对于需要快速访问和低延迟连接的用户群体。美西VPS的设计理念是为用户提供高性能和高可靠性的服务,同时确保在数据传输时的安全性。 美西VPS...

    原生IP的重要性及其在外贸中的应用价值

    原生IP的定义与特点 谈到原生IP,这个概念在网络世界中显得极为重要。简单来说,原生IP是指那些与虚拟专用服务器(VPS)所在国家一致的IP地址。这意味着,它们的注册信息和其实际位置是相符的,根本没有经过修改或伪造。这一点在外贸业务中尤为重要,很多情况下,企业需要保证他们的服务器IP地址真的是注册所...