隨筆 - 1  文章 - 37  trackbacks - 0
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          留言簿(16)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          test

          搜索

          •  

          最新評論

          一、Spring Framework
          通常Spring的web應(yīng)用結(jié)構(gòu)層次:
          1,ContextLoaderServlet,創(chuàng)建一個ContextLoader做為整個web應(yīng)用的Loader,它會為自己創(chuàng)建一個web應(yīng)用級別的WebApplicationContext,接著默認加載applicationContext.xml里面的bean
          2,DispatcherServlet,同樣創(chuàng)建一個WebApplicationContext,加載dispatch-bean,它會將ContextLoader的WebApplicationContext做為自己的父ApplicationContext

          二、Spring-OSGI
          通過Spring-osgi規(guī)范可以了解到spring-osgi會為每一個有spring-bean配置文件的bundle創(chuàng)建一個ApplicationContext,spring-bean配置文件里面的bean則被它加載,所以Dispatch-bean-loader無法找到spring-osgi-bean

          三、RESOLVER
          首先要先得到bundle的ApplicationContext,然后創(chuàng)建一個自定義的ContextLoader-BundleContextLoader,不加載配置文件,重寫loadParentContext方法,將父ApplicationContext設(shè)置成bundle的ApplicationContext,然后生成一個自定義的WebApplicationContext-BundleWebApplicationContext,里面的bean信息直接從parentApplicationContext里面獲取。本來spring規(guī)范里面寫著org.springframework.osgi.context.support.WebApplicationContext ,但是找個底朝天,也沒找到,可能還沒出呢吧,于是只能自己寫了。
          bundle的ApplicationContext可通過org.springframework.context.ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext)得到

          四、BundleContextLoaderServlet
          在org.phrancol.osgi.jpetstore.springmvc里新建類BundleContextLoaderServlet
          public class BundleContextLoaderServlet extends ContextLoaderServlet {
              
          private final ApplicationContext applicationContext;
              
          private BundleContext ctx;

              
          public BundleContextLoaderServlet(BundleContext ctx,
                      ApplicationContext appContext) 
          {
                  
          this.ctx = ctx;
                  
          this.applicationContext = appContext;
              }

              
              
          /**
               * 重寫該方法,用于構(gòu)造一個自定義的BundleContextLoader
               
          */

              
          protected ContextLoader createContextLoader() {
                  
          return new BundleContextLoader(applicationContext, ctx);
              }

          }
          五、BundleContextLoader
          在org.phrancol.osgi.jpetstore.springmvc里新建類BundleContextLoader
          public class BundleContextLoader extends ContextLoader {
              
          private final ApplicationContext applicationContext;
              
          private BundleContext bundleContext;

              
          public BundleContextLoader(ApplicationContext appContext, BundleContext ctx) {
                  
          this.applicationContext = appContext;
                  
          this.bundleContext = ctx;
              }

              
              
          /**
               * 重寫該方法,讓其返回的ParentContext是Bundle里的那個ApplicationContext
               
          */

              
          protected ApplicationContext loadParentContext(ServletContext servletContext)
                      
          throws BeansException {
                  
          return applicationContext;
              }


              
          /**
               * 生成一個自定義的BundleWebApplicationContext,返回的bean信息直接從Parent獲取
               * 這里的代碼請參考org.springframework.osgi.extender.support.ApplicationContextCreator.run()方法里的代碼
               
          */

              
          protected WebApplicationContext createWebApplicationContext(
                      ServletContext servletContext, ApplicationContext parent)
                      
          throws BeansException {
                  ClassLoader contextClassLoader 
          = Thread.currentThread()
                          .getContextClassLoader();
                  
          try {
                      ClassLoader cl 
          = BundleDelegatingClassLoader
                              .createBundleClassLoaderFor(bundleContext.getBundle(), getClass()
                                      .getClassLoader());
                      Thread.currentThread().setContextClassLoader(cl);
                      LocalBundleContext.setContext(bundleContext);
                      
          return new BundleWebApplicationContext(parent, servletContext);
                  }
           finally {
                      Thread.currentThread().setContextClassLoader(contextClassLoader);
                  }

              }

          }

          六、BundleWebApplicationContext
          在org.phrancol.osgi.jpetstore.springmvc里面新建類BundleWebApplicationContext,所有的方法都返回parent的方法返回值
          public class BundleWebApplicationContext implements WebApplicationContext {
              
              
          private final ApplicationContext parentApplicationContext;
              
          private ServletContext servletContext;
              
              
          public BundleWebApplicationContext(ApplicationContext parentApplicationContext,
                      ServletContext servletContext)
          {
                  
          this.parentApplicationContext = parentApplicationContext;
                  
          this.servletContext = servletContext;
              }


              
          public ServletContext getServletContext() {
                  
          // TODO Auto-generated method stub
                  return servletContext;
              }


              
          public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
                      
          throws IllegalStateException {
                  
          // TODO Auto-generated method stub
                  return parentApplicationContext.getAutowireCapableBeanFactory();
              }


              
          public String getDisplayName() {
                  
          // TODO Auto-generated method stub
                  return parentApplicationContext.getDisplayName();
              }

                  .
          }

          七、修改
          1,修改接口HttpServiceRegister.serviceRegister(BundleContext context),改成
          serviceRegister(BundleContext context, ApplicationContext bundleApplicationContext);
          2,修改SpringmvcHttpServiceRegister.serviceRegister(BundleContext context),改成
          serviceRegister(BundleContext context, ApplicationContext bundleApplicationContext)
          3,SpringmvcHttpServiceRegister.serviceRegister方法修改一下
          public void serviceRegister(BundleContext context, ApplicationContext bundleApplicationContext) {
                  
          try {
                      ServiceReference sr 
          = context.getServiceReference(HttpService.class
                              .getName());
                      HttpService httpService 
          = (HttpService) context.getService(sr);
                      httpService.registerResources(
          "/""/web"null);
                      httpService.registerServlet(
          "/*.jsp"new JspServlet(context
                              .getBundle(), 
          "/web"), nullnull);
                      Dictionary
          <String, String> initparams = new Hashtable<String, String>();
                      initparams.put(
          "load-on-startup""1");
                     
          /*  編輯器的問題,這4行代碼不是注釋。。。 */
                      ContextLoaderServlet contextloaderListener = new BundleContextLoaderServlet(
                              context, bundleApplicationContext);
                      httpService.registerServlet("/ContextLoader",
                              contextloaderListener, initparams, null);
                      /*   
          */

                      DispatcherServlet dispatcherServlet 
          = new DispatcherServlet();
                      dispatcherServlet
                              .setContextConfigLocation(
          "META-INF/dispatcher/petstore-servlet.xml");
                      initparams 
          = new Hashtable<String, String>();
                      initparams.put(
          "servlet-name""petstore");
                      initparams.put(
          "load-on-startup""2");
                      httpService.registerServlet(
          "/*.do", dispatcherServlet, initparams,
                              
          null);
                  }
           catch (Exception e) {
                      e.printStackTrace(System.out);
                  }

              }

          OK,這下應(yīng)該沒問題了,啟動看看效果
          倒,還是報錯。。。。。。

          八、HttpContext
          來看看org.osgi.service.http.HttpService.registerServlet的代碼
            * Servlets registered with the same <code>HttpContext</code> object will
            * share the same <code>ServletContext</code>.
          原來是這樣,注冊了2個servlet,于是生成了2個不同的HttpContext,那就只生成一個試試
          HttpContext defaultContext = new DefaultHttpContext(context.getBundle());

          httpService.registerServlet(
          "/init-context-loader-petsore-web",
                              contextloaderListener, initparams, defaultContext);

          httpService.registerServlet(
          "/*.do", dispatcherServlet, initparams,
                              defaultContext);
          再啟動,一切順利,訪問頁面也正常。

          九、打完收工
          將org.phrancol.osgi.jpetstore.springmvc/METS-INF/dispatcher/petstore-servlet.xml里面的bean補全(注意還有2個bean需要注冊和引用),再運行,就OK了。
          posted on 2007-09-07 18:15 Phrancol Yang 閱讀(2343) 評論(1)  編輯  收藏 所屬分類: OSGI

          FeedBack:
          # re: Developing Equinox/Spring-osgi/Spring Framework Web Application Part 3 - 找到我的Bean 2007-09-08 13:05 Friszart
          OSGI的確是有它的優(yōu)越性,但還是個復(fù)雜的東東,
          猜還是得等到OSGI on Rails之類的框架發(fā)明后,才可能真正流行起來。  回復(fù)  更多評論
            
          主站蜘蛛池模板: 收藏| 陇西县| 玉溪市| 平定县| 浑源县| 宁都县| 鄂伦春自治旗| 内丘县| 临安市| 永福县| 灵山县| 武汉市| 寿阳县| 白银市| 壶关县| 衡南县| 太湖县| 鄂温| 桃江县| 土默特右旗| 石嘴山市| 黔西县| 上饶县| 加查县| 军事| 南阳市| 玛沁县| 普陀区| 句容市| 措勤县| 靖远县| 黄龙县| 苗栗县| 花莲市| 台北市| 达州市| 邹平县| 调兵山市| 综艺| 阳山县| 东乌珠穆沁旗|