使用Proxy.newProxyInstance包装对象池,免去returnObject方法调用

04-12-07 stephen
希望能实现一个对象池,但是同时要避免调用returnObject。

因为如果可以避免调用returnObject,那么就原来的代码就可以不做修改就能使用对象池优化功能了。

下面是为了实现上述功能写的示例代码。

先声明一点,准备保存到池里面的对象是不用在两次调用之间保存状态的。

所以下面的示例代码中,每次调用一个方法的时候,都从池里面找一个对象,用完之后,立即归还。

所以原来的代码中,每次使用对象的时候,从工厂里面new一个对象出来,使用完了也不做任何处理。

类似如下代码。

....
SamplePortType obj = new SampleClass();
obj.helloWorld();
....

<p>

另外,由于是示例代码,所以里面涉及多线程同步的问题也做处理。

代码虽然写了出来,就这个示例程序来说,也能跑了,

但是对其中的实现方法存在一些疑问。

主要的疑问是,示例代码中,Proxy.newProxyInstance 每次都是使用同样的一个对象来创建动态代理,

然后实际invoke(Object proxy, Method method, Object[] args)的时候,使用另外一个对象去执行。

不知道这样做会不会存在问题?

不知道为了实现刚开始提出的问题,有什么其他办法?

import java.util.logging.*;
import java.util.Stack;
import java.lang.reflect.*;
import java.lang.Object;
import java.lang.System;

interface SamplePortType {
  public void helloWorld ( );
};

class SampleClass implements SamplePortType {
  public SampleClass ( ) { }
  public void helloWorld ( ) {
    System.out.println ( "Hello world!" );
  }
};

class SamplePool {
  static private SamplePool _instance;
  static public SamplePool getInstance() {
    if ( null == _instance ) {
      _instance = new SamplePool();
    }
    return _instance;
  }

  private SamplePool ( ) { _pool = new Stack(); }

  public SamplePortType borrowObject ( ) {
    if ( _pool.empty() ) {
      return new SampleClass();
    } else {
      return (SamplePortType)_pool.pop();
    }
  }

  public void returnObject ( SamplePortType obj ) { _pool.push ( obj ); }

  private Stack _pool;
};

public class AOPHandler implements InvocationHandler {
  static private SamplePortType _orgObject = null;

  public static SamplePortType getObject ( ) {
    if ( null == _orgObject ) _orgObject = new SampleClass();
    return (SamplePortType)Proxy.newProxyInstance(
        _orgObject.getClass().getClassLoader(),
        _orgObject.getClass().getInterfaces(),
        new AOPHandler() );
  }

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

    SamplePortType obj = SamplePool.getInstance().borrowObject();
    Object result = null;
    result = method.invoke(obj, args);
    SamplePool.getInstance().returnObject ( obj );
    return result;
  }

  static public void main ( String args[] ) {
    SamplePortType obj = AOPHandler.getObject();
    obj.helloWorld ( );
  }
}

<p>
         

6
stephen
2004-12-07 15:49
上面的描述有些错别字,论坛好像没有办法对已经发表的帖子做修改,所以在这里加以说明一下:

1.所以原来的代码中,每次使用对象的时候,从工厂里面new一个对象出来,使用完了也不做任何处理。

类似如下代码。

....
SamplePortType obj = SampleFactory.getObject();
obj.helloWorld();
....
<p>

2.另外,由于是示例代码,所以里面涉及多线程同步的问题也“没”做处理。

stephen
2004-12-07 18:49

转贴一篇类似的讨论

☆─────────────────────────────────────☆
   gty (宜良-丽江-蝴蝶泉) 于  (Fri Feb 21 02:33:56 2003)  提到:

Session Pool Design

1. 利用apache common-pool实现一个Session Pool(非常简单)
2. 如何避免代码中的returnObject()?

       xxx()            invoke       
        --------> PoolProxy ---> PoolInterceptor      SessionPool
                                           borrowObject()
                                          --------------->
                                          <---------------
                                          
                                          
                                                   xxx()       Session (be borrowed)
                                          -------------------------------->
                                          
                                           returnObject()
                                          ---------------->



☆─────────────────────────────────────☆
   gty (宜良-丽江-蝴蝶泉) 于  (Fri Feb 21 02:38:01 2003)  提到:

RMI design

 xxx()            invoke               Serialize call to remote
-----> ClientProxy ---> RmiInterceptor ------------------->

         find ServerProxy, xxx()               xxx()
RmiServer----------------> ServerProxy --->....-->ServerObject



☆─────────────────────────────────────☆
   gty (宜良-丽江-蝴蝶泉) 于  (Fri Feb 21 02:43:37 2003)  提到:

Method Cache design

1.用HashMap做cache

 xxx()       invoke             
-----> Proxy ---> MCInterceptor 
                       1. get Attribute @timeout
                       2. 用object[]作为key,看cache中的
                       结果是否超时

                       3. 如果超时     invoke      
                         ------------------> NextInterceptor...
                       4. 如果不超,返回被cache的结果



☆─────────────────────────────────────☆
   gty (宜良-丽江-蝴蝶泉) 于  (Fri Feb 21 02:47:03 2003)  提到:

Draw activity UML diagram:

1. 实现绘图模块
xxx()      invoke
---> Proxy ---> ActivityIntercpetor 
                             draw xxx()   
                        --------------->绘图模块
                            invoke
                        --------------------------->NextInterceptor...



☆─────────────────────────────────────☆
   gty (宜良-丽江-蝴蝶泉) 于  (Fri Feb 21 02:53:04 2003)  提到:

Persistence and descriptive transaction

1. Persistence直接使用hibernate


xxx       invoke
---->Proxy-->HibernateInterceptor
                                1. 取得@tx,应该为required,requiresnew
                                ,supports,notsupported中的一种
                                2. 判断当前的transaction状态
                                3. 决定本次调用是否在transaction当中



☆─────────────────────────────────────☆
   gty (宜良-丽江-蝴蝶泉) 于  (Fri Feb 21 03:01:18 2003)  提到:

Folder-Node关系的复用


getFolder()   getFolder()         invoke              getFolder()
  --->UserProxy ------> NodeProxy -->SideEntityInterceptor--> Node 
                                                        return Folder
                                                        <-----
                                             根据Folder创建Group proxy 
                                  返回GroupProxy           
                                  <----
                                           
  
in the code, like this:

...
User user = userFactory.find("guty"); //user is actually a proxy
Group group = (Group)((Node)user).getFolder();
<p>

ljshan
2004-12-07 18:57
为什么创建动态代理的时候,对象不从pool中去取呢?另外对象池为什么要用堆栈处理,我觉得用HashSet这样的随机顺序比较好。

public static SamplePortType getObject2() {

SamplePortType _orgObject = SamplePool.getInstance().borrowObject();

return (SamplePortType) Proxy.newProxyInstance(

_orgObject.getClass().getClassLoader(),

_orgObject.getClass().getInterfaces(),

new AOPHandler());

}

这样处理的话,都是随机的了。

ljshan
2004-12-07 19:06
或者更加简洁安全的做法:

public static SamplePortType getObject2() {

SamplePortType _orgObject = new SamplePortType(){

public void helloWorld (){}

};

return (SamplePortType) Proxy.newProxyInstance(

_orgObject.getClass().getClassLoader(),

_orgObject.getClass().getInterfaces(),

new AOPHandler());

}

猜你喜欢
4Go 1 2 3 4 下一页