java 开发一个http的代理服务器

java 开发一个http的代理服务器,第1张

说实话,你的问题很那个。。

不过应该也能实现。

现在问题主要是由于b不能访问c,所以c只能使用TimerTask定时去访问b。

b有2个listener,一个负责侦听来自a的请求,一个负责侦听来自b的。

b中应该会使用到多线程。

下面定义a的Request为x,c的Request为y

由于b会有多个来自a转发的请求,可能会有x1\x2\x3等很多并发的请求,所以b在初始化的时候就需要建立一个等待池

等待池应该是单例且线程同步的,x一来就new object(request,response),然后放入list。

c的定时器一到,就访问b开放给c的listener,request y。y首先遍历等待池,取出x的request,然后用取出x的response的返回给a。直到等待池为空为止,然后y response给c。

不过要注意的是

1)你会发现,由于c给b的数据应该是放到request y里面作为参数来传的。

2)a的请求如果需要c不同数据接口的数据,那c-->b的request y里就应该包含所有的数据,然后在遍历等待池的时候根据a-->b的request x的id(可以使用sessionid)来区分取哪个。

3)最差的情况,

1,a源源不断的发出x请求,c的request遍历就死循环。

2,如果c的定时时间太短,y1还没完,y2就来了。

3,a源源不断的发出x请求,但是某一请求Xn就无法抢到资源,Xn就挂掉。

这里面很多处理你还要多加控制。

这个想法没实验过,其实如果b可以访问c,其实什么问题都没有了

最后问一句,谁给你这样的需求的?打他

在目前的Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。

其实现主要通过是javalangreflectProxy类和javalangreflectInvocationHandler接口。

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现,如下,HelloWorld接口定义的业务方法,HelloWorldImpl是HelloWorld接口的实现,HelloWorldHandler是InvocationHandler接口实现。代码如下:

业务接口:

public interface HelloWorld {

void sayHelloWorld() ;

}

业务接口实现:

public class HelloWorldImpl implements HelloWorld {

public void sayHelloWorld() {

Systemoutprintln("Hello World!");

}

}

InvocationHandler实现,需要在接口方法调用前后加入一部份处理工作,这里仅仅在方法调用前后向后台输出两句字符串,其代码如下:

import javalangreflectInvocationHandler;

import javalangreflectMethod;

public class HelloWorldHandler implements InvocationHandler {

//要代理的原始对象

private Object objOriginal;

/

构造函数。

@param obj 要代理的原始对象。

/

public HelloWorldHandler(Object obj) {

thisobjOriginal = obj ;

}

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

Object result ;

//方法调用之前

doBefore();

//调用原始对象的方法

result = methodinvoke(thisobjOriginal ,args);

//方法调用之后

doAfter();

return result ;

}

private void doBefore() {

Systemoutprintln("before method invoke!");

}

private void doAfter() {

Systemoutprintln("after method invoke!");

}

}

测试代码:

import javalangreflectInvocationHandler;

import javalangreflectProxy;

public class Test {

public static void main(String[] args) {

HelloWorld hw = new HelloWorldImpl();

InvocationHandler handler = new HelloWorldHandler(hw);

HelloWorld proxy = (HelloWorld) ProxynewProxyInstance(

hwgetClass()getClassLoader(),

hwgetClass()getInterfaces(),

handler);

proxysayHelloWorld();

}

}

Ø 首先获取一个业务接口的实现对象;

Ø 获取一个InvocationHandler实现,此处是HelloWorldHandler对象;

Ø 创建动态代理对象;

Ø 通过动态代理对象调用sayHelloWorld()方法,此时会在原始对象HelloWorldImpl sayHelloWorld()方法前后输出两句字符串。

运行测试类输出如下:

before method invoke!

Hello World!

after method invoke!

此处Test类中的方法调用代码比较多,在我们的实际应用中可以通过配置文件来来简化客户端的调用实现。另外也可以通过动态代理来实现简单的AOP。

需要使用代理。

使用Jsoup解析Url时,发现无论如何都不能解析,发现单位都是用的代理上网,可能和代理有关,所以,只要在程序中设置好代理就可以。

代理技术,其实不只是Java语言特有的技术,其实在互联网早期就已经出现了这种技术。在计算机网络层面,常用的代理技术有,正向代理、反向代理和透明代理。

使用代理类可以在实现类的基础上进行扩展,可以在方法中动态加入代码。这里要理解的是,实现类和代理类都是继承了同一个接口的(必须的)举个例子,如果你要通过一个实现类,将文本控件中输入的数字,做 加减乘除(也许还有很多运算) 法的运算,你发现这样会有一些问题存在,字符串如果不能转换成数字,就会报错。那么,你必须在方法的开头加入验证判断。但是,你又发现每个方法都要写验证是很麻烦的,而且代码量也会很多。于是你将验证抽取出来,成为一个方法。 每个运算方法都在开头调用这个验证就行了。这样是没有问题的。然而,如果这个实现类不是你写的,是A程序员写的,而A程序员觉得他无法知道,使用这个实现类的程序员是否希望验证这个字符串,所以,他把字符串的验证工作交给了调用的程序员。而你在使用这个实现类的时候,你不能修改这个实现类,给他的每个方法开头加入字符串的验证。那么怎么去让这个实现类的每个运算方法都在调用前都去验证一下呢?代理就可以动态的在每个方法前加入验证,比如add(int,int)方法,如果调用代理类的方法,代理类将先做验证,然后再去调用实现类的方法。这个是有必要的,因为代理的动态的加入验证代码,不需要每个方法钱都加入验证。最后总结一下,代理的作用大多是实现类的实现,对于调用者特定功能来说,做的还不够,这代理,可以加入那些还不够的代码,然后再去调用实现类。

  代理模式( )

代理模式也是一种很常见的设计模式 它使用代理对象完成用户请求 屏蔽用户对真实对象的访问 就如同现实中的代理一样 代理人被授权执行当事人的一些事宜 而无需当事人出面 从第三方的角度看 似乎当事人并不存在 因为他只和代理人通信 而事实上 代理人是要有当事人的授权 并且在核心问题上还需要请示当事人

在现实中 使用代理的情况很普遍 而且原因也很多 比如 当事人因为某些隐私不方便出面 或者当事人不具备某些相关的专业技能 而需要一个职业人员来完成一些专业的 *** 作 也可能由于当事人没有时间处理事务 而聘用代理人出面

在软件设计中 使用代理模式的意图也很多 比如因为安全原因 需要屏蔽客户端直接访问真实对象 或者在远程调用中 需要使用代理类处理远程方法调用的技术细节(如RMI) 也可能是为了提升系统性能 对真实对象进行封装 从而达到延迟加载的目的 在本小节中 主要讨论使用代理模式实现延迟加载 从而提升系统的性能和反应速度

代理模式的结构

代理模式的主要参与者有 个 如表 所示

表   代理模式角色

以一个简单的示例来阐述使用代理模式实现延迟加载的方法及其意义 假设某客户端软件 有根据用户请求 去数据库查询数据的功能 在查询数据前 需要获得数据库连接 软件开启时 初始化系统的所有类 此时尝试获得数据库连接 当系统有大量的类似 *** 作存在时(比如xml解析等) 所有这些初始化 *** 作的叠加 会使得系统的启动速度变得非常缓慢 为此 使用代理模式 使用代理类 封装对数据库查询中的初始化 *** 作 当系统启动时 初始化这个代理类 而非真实的数据库查询类 而代理类什么都没有做 因此 它的构造是相当迅速的

在系统启动时 将消耗资源最多的方法都使用代理模式分离 就可以加快系统的启动速度 减少用户的等待时间 而在用户真正做查询 *** 作时 再由代理类 单独去加载真实的数据库查询类 完成用户的请求 这个过程就是使用代理模式实现了延迟加载

注意 代理模式可以用于多种场合 如用于远程调用的网络代理 考虑安全因素的安全代理等 延迟加载只是代理模式的一种应用场景

延迟加载的核心思想是 如果当前并没有使用这个组件 则不需要真正地初始化它 使用一个代理对象替代它的原有的位置 只要在真正需要使用的时候 才对它进行加载 使用代理模式的延迟加载是非常有意义的 首先 它可以在时间轴上分散系统压力 尤其在系统启动时 不必完成所有的初始化工作 从而加速启动时间 其次 对很多真实主题而言 在软件启动直到被关闭的整个过程中 可能根本不会被调用 初始化这些数据无疑是一种资源浪费 图 显示了使用代理类封装数据库查询类后 系统的启动过程

图   代理类的工作流程

若系统不使用代理模式 则在启动时就要初始化DBQuery对象 而使用代理模式后 启动时只需要初始化一个轻量级的对象DBQueryProxy

系统的结构图如图 所示 IDBQuery是主题接口 定义代理类和真实类需要对外提供的服务 在本例中了定义了实现数据库查询的公共方法request()函数 DBQuery是真实主题 负责实际的业务 *** 作 DBQueryProxy是DBQuery的代理类

       返回目录 Java程序性能优化 让你的Java程序更快 更稳定

编辑推荐

       Java程序设计培训视频教程

       J EE高级框架实战培训视频教程

       J ME移动开发实战教学视频

Visual C++音频/视频技术开发与实战

Oracle索引技术

lishixinzhi/Article/program/Java/gj/201311/27834

  代理模式( )

在以上代码中 使用CtField make()方法和CtNewMehod make()方法在运行时生成了代理类的字段和方法 这些逻辑由Javassist的CtClass对象处理 将Java代码转换为对应的字节码 并生成动态代理类的实例

注意 与静态代理相比 动态代理可以很大幅度地减少代码行数 并提升系统的灵活性

在Java中 动态代理类的生成主要涉及对ClassLoader的使用 这里以CGLIB为例 简要阐述动态类的加载过程 使用CGLIB生成动态代理 首先需要生成Enhancer类实例 并指定用于处理代理业务的回调类 在Enhancer create()方法中 会使用DefaultGeneratorStrategy Generate()方法生成动态代理类的字节码 并保存在byte数组中 接着使用ReflectUtils defineClass()方法 通过反射 调用ClassLoader defineClass()方法 将字节码装载到ClassLoader中 完成类的加载 最后使用ReflectUtils newInstance()方法 通过反射 生成动态类的实例 并返回该实例 无论使用何种方法生成动态代理 虽然实现细节不同 但主要逻辑都如图 所示

图   实现动态代理的基本步骤

前文介绍的几种动态代理的生成方法 性能有一定差异 为了能更好地测试它们的性能 去掉DBQuery类中的sleep()代码 并使用以下方法测试

public static final int CIRCLE= ;

public static void main(String[] args) throws Exception {

IDBQuery d=null;

long begin=System currentTimeMillis()

d=createJdkProxy()                      //测试JDK动态代理

System out println( createJdkProxy: +(System currentTimeMillis() beg    in))

System out println( JdkProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callJdkProxy: +(System currentTimeMillis() begin    ))

begin=System currentTimeMillis()

d=createCglibProxy()                    //测试CGLIB动态代理

System out println( createCglibProxy: +(System currentTimeMillis() b    egin))

System out println( CglibProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callCglibProxy: +(System currentTimeMillis() beg    in))

begin=System currentTimeMillis()

d=createJavassistDynProxy()             //测试Javaassist动态代理

System out println( createJavassistDynProxy: +(System currentTimeMil    lis() begin))

System out println( JavassistDynProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callJavassistDynProxy: +(System currentTimeMilli    s() begin))

begin=System currentTimeMillis()

d=createJavassistBytecodeDynamicProxy()     //测试Javassist动态代理

System out println( createJavassistBytecodeDynamicProxy: +(System cu    rrentTimeMillis() begin))

System out println( JavassistBytecodeDynamicProxy class: +d getClass()

getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callJavassistBytecodeDynamicProxy: +(System curr    entTimeMillis() begin))

}

       返回目录 Java程序性能优化 让你的Java程序更快 更稳定

编辑推荐

       Java程序设计培训视频教程

       J EE高级框架实战培训视频教程

       J ME移动开发实战教学视频

Visual C++音频/视频技术开发与实战

Oracle索引技术

lishixinzhi/Article/program/Java/gj/201311/27830

使用Proxy来对每个连接实现代理, 这种方法只能在jdk 15以上的版本使用(包含jdk15), 优点是可以单独的设置每个连接的代理, 缺点是设置比较麻烦:

public static void main(String[] args) {

try {

URL url = new URL(">

Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地制定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分配到委托对象上反射执行,配置执行过程中,开发人员还可以进行修改

代理设计模式

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息、过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

为了保持行为的一致性,代理类和委托类通常会实现相同的接口

2 引入代理能够控制对委托对象的直接访问,可以很好的隐藏和保护委托对象,也更加具有灵活性

代理机制及其特点

首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:

通过实现 InvocationHandler 接口创建自己的调用处理器;

通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;

通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;

通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

代理类实例的一些特点 

每个实例都会关联一个InvocationHandler(调用处理器对象),在代理类实例上调用其代理接口中声明的方法时,最终都会由InvocationHandler的invoke方法执行;

javalangObject中有三个方法也同样会被分派到调用处理器的 invoke 方法执行,它们是 hashCode,equals 和 toString;

代码示例

最后以一个简单的动态代理例子结束

以上就是关于java 开发一个http的代理服务器全部的内容,包括:java 开发一个http的代理服务器、java动态代理怎样实现、java的网络代理设置和自己的网络代理软件有冲突等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9791233.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存