<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Vincent.Chan‘s Blog

    常用鏈接

    統計

    積分與排名

    網站

    最新評論

    Webwork 2.2的Action是否使用Spring的prototype-獲取的性能對比

    1、引子:
    其實是ajoo的這篇“Nuts和Spring 1.2.6 效率對比”和“IoC容器的prototype性能測試 ”,他們在Javaeye上詳細討論了Spring的prototype的缺陷。
    Spring的prototype指的就是singleton="false"的bean,具體可以看Spring參考手冊“3.2.5. To singleton or not to singleton”介紹。

    2、Webwork 2.2的Spring結合問題:
    Webwork 2.2已經拋棄自己的IoC,默認使用Spring的IoC。
    上在OpenSymphony的官方Wiki,和jscud后來的幾篇文章中沒有特別提出prototype的問題。但是托他們的福,我們已經順利的使Spring和Webwork良好的協同工作起來了。
    可是而后的一些問題卻把prototype的問題搞得神秘起來……
    ajoo的測試中指出Spring的prototype性能很差,參見后面參考中的一篇文章和Javaeye的討論。
    而后又發現robbin在Javaeye的Wiki上面的“集成webwork和spring”中的最后注到:
    “注意:目前并不推薦使用Spring來管理Webwork Action,因為對于prototype類型的bean來說,Spring創建bean和調用bean的效率是很低的!更進一步信息請看IoC容器的prototype性能測試”
    這就使我們常用的Spring+Webwork2.2的連接中使用的prototype的問題被擺出來了。
    我現在的項目中使用了prototype的方式將Webwork Action使用Spring進行顯示的裝配,我擔心這個性能的問題會很嚴重,所以今天花了半天時間具體測試了一下。

    3、Prototype VS autowire的解釋:
    我不知道怎么命名兩種方式好,所以這里先做個解釋:
    spring的配置中Action會有個id,如:

    <bean id="someAction" class="com.tin.action.SomeAction" parent="basicActionWithAuthtication" singleton="false">
     
    <property name="someDAO">
      
    <ref bean="someDAO" />
     
    </property>
    </bean>

    我指的prototype方式就是在xwork中這樣配置:

    <action name="someAction" class="someAction">

    而autowire方式就是指在xwork中這樣配置:

    <action name="someAction" class="com.tin.action.SomeAction">

    看起來相同,但其實不同(我以前發過帖子,其中說這幾種方法都可,但是其實它們的機制是不同的。

    4、Portotye和autowire在XWork的SpringObjectFactory中是如何運作的:
    我們先看一下代碼,就能明白兩者的區別了:

    public Object buildBean(String beanName, Map extraContext) throws Exception {
     
    try {
                
    return appContext.getBean(beanName);
            }
     catch (NoSuchBeanDefinitionException e) {
                Class beanClazz 
    = getClassInstance(beanName);
                
    return buildBean(beanClazz, extraContext);
            }

        }


        
    public Object buildBean(Class clazz, Map extraContext) throws Exception {
            Object bean;

            
    try {
                bean 
    = autoWiringFactory.autowire(clazz, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
            }
     catch (UnsatisfiedDependencyException e) {
                
    // Fall back
                bean = super.buildBean(clazz, extraContext);
            }


            bean 
    = autoWiringFactory.applyBeanPostProcessorsBeforeInitialization(bean, bean.getClass().getName());
            
    // We don't need to call the init-method since one won't be registered.
            bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean, bean.getClass().getName());

            
    return autoWireBean(bean, autoWiringFactory);
        }


        
    public Object autoWireBean(Object bean) {
            
    return autoWireBean(bean, autoWiringFactory);
        }


    如果按照autowire配置會使用第二個buildBean方法,而prototype會使用第一個buildBean方法。

    5、我的測試,首先測試SpringObjectFactory的理論效率:

    public class testSpringObjectFactory extends TestCase {
        
    protected FileSystemXmlApplicationContext appContext;
        
    protected SpringObjectFactory sof = null;
        
    protected Map map = null;
        
    final String[] paths = {
                
    "WebRoot/WEB-INF/applicationContext.xml",
                
    "WebRoot/WEB-INF/spring-daos.xml",
                
    "WebRoot/WEB-INF/spring-actions.xml"
            }
    ;

        
    protected void setUp() throws Exception {
            
    super.setUp();
            appContext 
    = new FileSystemXmlApplicationContext(paths);

            sof 
    = new SpringObjectFactory();
            sof.setApplicationContext(appContext);
            sof.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);

            map 
    = new HashMap();
        }


        
    public void testSpringObjectFacotyWithAutowire() {
            
    long begin = System.currentTimeMillis();

            
    try {
                
    for (int i = 0; i < 100000; i++{
                    sof.buildBean(
    "com.wqh.action.XinfangNewsAction", map);
                }

            }
     catch (Exception e) {
                e.printStackTrace();
            }


            
    long end = System.currentTimeMillis();
            System.out.println(
    "**************************Used time:" +
                (begin 
    - end));
        }


        
    public void testSpringObjectFacotyWithPrototype() {
            
    long begin = System.currentTimeMillis();

            
    try {
                
    for (int i = 0; i < 100000; i++{
                    sof.buildBean(
    "xinfangNewsAction", map);
                }

            }
     catch (Exception e) {
                e.printStackTrace();
            }


            
    long end = System.currentTimeMillis();
            System.out.println(
    "**************************Used time:" +
                (begin 
    - end));
        }

        
        
    public void testSpringObjectFacotyWithSpringProxyableObjectFactory() {
            sof 
    = new SpringProxyableObjectFactory();
            sof.setApplicationContext(appContext);
            sof.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);

            
    long begin = System.currentTimeMillis();

            
    try {
                
    for (int i = 0; i < 100000; i++{
                    sof.buildBean(
    "com.wqh.action.XinfangNewsAction", map);
                }

            }
     catch (Exception e) {
                e.printStackTrace();
            }


            
    long end = System.currentTimeMillis();
            System.out.println(
    "**************************Used time:" +
                (begin 
    - end));
        }

    }

     

    重要的是測試結果:
    **************************Used time:-16875
    **************************Used time:-80500
    **************************Used time:-12703(使用SpringProxyableObjectFactory()這個實現)

    prototype是autowire運行時間的4.77X倍,十分可觀。

    6、在實際的Web項目中的性能對比:
    我使用了我的一個小項目,就是反復調用一個action獲取一個頁面,其中有一個DAO注入。使用了JMeter進行了一個測試:2個線程,間隔0.5秒,循環50次,對比“據和報告中的”Throughput,單位/sec。
    使用autowire方式:Avg. 148.34(吞吐量越高越好)
    使用prototype方式:Avg. 138.5

    也就是說在實際應用中兩者也是有性能差距的,后者大約是前者性能的93%。
    具體代碼我不放出了,因為意義不大,大家也可以自己動手試驗一下。

    7、后續:
    如果理想測試下兩者性能差距4.7倍,實際性能差距在7%左右。這基本上讓我心里有點底了。
    但是使用autowire還是有trade off的。失去了Spring的顯示配置,也難使用Spring的AOP支持,這樣Spring的聲明性事務就不容易使用了,像Acegi這樣的安全框架也難以使用。所以這需要自己選擇了。
    但 是注意5中結果里面的SpringProxyableObjectFactory性能非常好,我看了下代碼,它將調用過的bean注冊到Spring的 BeanRegistry中,性能還是很不錯的,但是為什么快我還沒有仔細看,如何配置我也不太清楚,希望明白的朋友跟進講解。

    8、參考資源:
    Nuts和Spring 1.2.6 效率對比
    http://www.javaeye.com/pages/viewpage.action?pageId=786
    IoC容器的prototype性能測試
    http://forum.javaeye.com/viewtopic.php?t=17622&postdays=0&postorder=asc&start=0
    JavaEye的Wiki:集成webwork和spring
    http://www.javaeye.com/pages/viewpage.action?pageId=860
    WebWork - Spring官方Wiki
    http://www.opensymphony.com/webwork/wikidocs/Spring.html
    webwork2 + spring 結合的幾種方法的小結
    http://www.tkk7.com/scud/archive/2005/09/21/13667.html

    posted on 2006-02-14 23:30 Vincent.Chen 閱讀(608) 評論(0)  編輯  收藏 所屬分類: WebWork&Struts

    主站蜘蛛池模板: 全部免费a级毛片| 免费精品一区二区三区在线观看| 亚洲精品tv久久久久| 亚洲s码欧洲m码吹潮| 日韩午夜免费视频| 在线观看国产一区亚洲bd| 国产无遮挡吃胸膜奶免费看视频| 亚洲美国产亚洲AV| 四虎影在线永久免费四虎地址8848aa| 苍井空亚洲精品AA片在线播放 | 一个人看的免费高清视频日本 | 亚洲AV福利天堂一区二区三| 亚洲国模精品一区| 72pao国产成视频永久免费| 国产乱辈通伦影片在线播放亚洲| 国产99精品一区二区三区免费 | 亚洲乱码日产精品BD在线观看| 国产免费久久精品99re丫y| 亚洲人成人伊人成综合网无码| 亚洲不卡AV影片在线播放| 亚洲av永久无码嘿嘿嘿| 日韩免费无码一区二区视频| 一个人看的免费观看日本视频www 一个人看的免费视频www在线高清动漫 | 亚洲精品99久久久久中文字幕| 国产成人无码精品久久久免费 | 亚洲成亚洲乱码一二三四区软件| 久久久久国产免费| 亚洲香蕉久久一区二区三区四区| 成人奭片免费观看| 七次郎成人免费线路视频| 亚洲va久久久噜噜噜久久| 亚洲一区在线免费观看| 亚洲码和欧洲码一码二码三码| 国产午夜亚洲精品国产成人小说| 免费A级毛片无码A∨| 亚洲成av人片在www鸭子| 亚洲国产一二三精品无码| 99久久这里只精品国产免费| 特级毛片aaaa免费观看| 亚洲综合国产精品| 国产jizzjizz免费看jizz|