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

          留言簿(16)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          test

          搜索

          •  

          最新評論

          一、域模型
          先從最底層開始,把域模型建立起來,創建一個Plug-in project -

          org.phrancol.osgi.jpetstore.domain,不創建Activator,創建一個package - org.phrancol.osgi.jpetstore.domain,將src\org\springframework\samples\jpetstore\domain 里面的java文件copy進去(重構一下package的名字,java文件里的package自動就變了,不用改每個文件),在MANIFEST.MF里面把依賴包導入一下并export這個package
          domain里面的logic,引用了dao,dao也引用了domain,會導致一個錯誤,于是將logic做為一個獨立的bundle,就稱為域邏輯吧

          二、域邏輯
          創建一個Plug-in project - org.phrancol.osgi.jpetstore.domain.logic,不創建Activator,創建一個同名package,將jpetstore\src\org\springframework\samples\jpetstore\domain\logic里面的java文件copy進去,在MANIFEST.MF里面把依賴包導入

          三、DAO
          該做dao部分了,創建一個 Plug-in project - org.phrancol.osgi.jpetstore.dao 并創建一個同名package,將jpetstore\src\org\springframework\samples\jpetstore\dao里面的東西全部copy進去,在MANIFEST.MF里面導入依賴包(有一些包需要導入成bundle,例如 spring-jdbc,spring-ibatis),啟動看看,發現spring-ibatis和persistence沒有啟動,手動啟動spring-ibatis,發現缺少ibatis,于是 New-> Other -> Plug-in from existing JAR archives ,導入ibatis,再啟動,發現少 javax.transaction,于是用相同方法導入。

          四、配置文件
           關于spring的配置文件,只有3個
          petstore-servlet.xml - 用于mvc的,定義dispatch bean
          applicationContext.xml - 用于域邏輯的
          dataAccessContext-local.xml - 用于DAO的,定義了DataSource
          (一)dataAccessContext-local.xml
          1,將 jdbc.properties和sql-map-config.xml拷貝到META-INF目錄里,sql-map-config.xml里面的資源路徑可能需要修改一下,maps里面的模型的class屬性也需要改一下
          2,在META-INF目錄中創建一個目錄spring,將dataAccessContext-local.xml拷貝進去,將applicationContext.xml里面的加載jdbc.properties的bean移植過來,放在DataSource的上面
          <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                  
          <property name="locations">
                      
          <list>
                          
          <value>META-INF/jdbc.properties</value>
                      
          </list>
                  
          </property>
              
          </bean>


          再把dataAccessContext-local.xml里面的dao-bean->class屬性值修改一下,再把sqlMapClient的configLocation的值修改成META-INF/sql-map-config.xml,例如
          <!-- SqlMap setup for iBATIS Database Layer -->
              
          <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
                  
          <property name="configLocation" value="META-INF/sql-map-config.xml"/>
                  
          <property name="dataSource" ref="dataSource"/>
              
          </bean>


              
          <!-- ========================= DAO DEFINITIONS: IBATIS IMPLEMENTATIONS ========================= -->

              
          <bean id="accountDao" class="org.phrancol.sogi.jpetstore.dao.ibatis.SqlMapAccountDao">
                  
          <property name="sqlMapClient" ref="sqlMapClient"/>
              
          </bean>
          3,啟動,報錯,找不到ibatis的某個類,報錯信息如下
          org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.orm.ibatis.SqlMapClientFactoryBean]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
          Caused by: java.lang.NoClassDefFoundError: com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
              at org.springframework.orm.ibatis.SqlMapClientFactoryBean.
          class$(SqlMapClientFactoryBean.java:72)
          看來是spring-ibatis找不到com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig,來看看spring-ibatis的MANIFEST.MF,Dependencies的Import Packages, 加上com.ibatis.sqlmap.engine.transaction.external,再啟動,找不到DBCP,導入common-DBCP和common-pool,再啟動,正常,SS一下,還是正常

          (二)applicationContext.xml
          1,在org.phrancol.osgi.jpetstore.domain.logic的META-INF目錄中創建一個目錄spring,將applicationContext.xml拷貝進去,并改名為 logic-context.xml,刪除propertyConfigurer這個bean,因為它已經被移到了dataAccessContext-local.xml里面,將里面的bean的class屬性修改一下,啟動,發現缺少org.aspectj,導入一個,再啟動,報錯
          Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'accountDao' is defined
          無法找到 accountDao,accountDao被定義在org.phrancol.osgi.jpetstore.dao里面了,于是現在需要使用spring-osgi 來進行跨bundle的引用了。
          2,org.phrancol.osgi.jpetstore.dao/META-INF/spring目錄中創建一個spring配置文件dataAccessContext-local-osgi.xml,使用<osgi:service>將accountDao和其他被引用的DAO注冊成為OSGI Service
          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
              xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:osgi
          ="http://www.springframework.org/schema/osgi"
              xsi:schemaLocation
          ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"
          >
              
              
          <osgi:service id="accountDaoOsgi" ref="accountDao"
                  interface
          ="org.phrancol.osgi.jpetstore.dao.AccountDao">
              
          </osgi:service>
              
              
          <osgi:service id="categoryDaoOsgi" ref="categoryDao"
                  interface
          ="org.phrancol.osgi.jpetstore.dao.CategoryDao">
              
          </osgi:service>
              
              
          <osgi:service id="productDaoOsgi" ref="productDao"
                  interface
          ="org.phrancol.osgi.jpetstore.dao.ProductDao">
              
          </osgi:service>
              
              
          <osgi:service id="itemDaoOsgi" ref="itemDao"
                  interface
          ="org.phrancol.osgi.jpetstore.dao.ItemDao">
              
          </osgi:service>
              
              
          <osgi:service id="orderDaoOsgi" ref="orderDao"
                  interface
          ="org.phrancol.osgi.jpetstore.dao.OrderDao">
              
          </osgi:service>
              
          </beans>

          3,在org.phrancol.osgi.jpetstore.domain.logic/META-INF/spring 也創建一個spring配置文件logic-context-osgi.xml,使用<osgi:reference>獲取服務
          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
              xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:osgi
          ="http://www.springframework.org/schema/osgi"
              xsi:schemaLocation
          ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
              http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"
          >

              
          <osgi:reference id="accountDaoOsgi" interface="org.phrancol.osgi.jpetstore.dao.AccountDao"/>

              
          <osgi:reference id="categoryDaoOsgi" interface="org.phrancol.osgi.jpetstore.dao.CategoryDao"/>

              
          <osgi:reference id="productDaoOsgi" interface="org.phrancol.osgi.jpetstore.dao.ProductDao"/>

              
          <osgi:reference id="itemDaoOsgi" interface="org.phrancol.osgi.jpetstore.dao.ItemDao"/>

              
          <osgi:reference id="orderDaoOsgi" interface="org.phrancol.osgi.jpetstore.dao.OrderDao"/>
              
          </beans>
          將logic-context.xml里面的bean  petStore的屬性引用修改一下
          <bean id="petStore" class="org.phrancol.osgi.jpetstore.domain.logic.PetStoreImpl">
                  
          <property name="accountDao" ref="accountDaoOsgi"/>
                  
          <property name="categoryDao" ref="categoryDaoOsgi"/>
                  
          <property name="productDao" ref="productDaoOsgi"/>
                  
          <property name="itemDao" ref="itemDaoOsgi"/>
                  
          <property name="orderDao" ref="orderDaoOsgi"/>
              
          </bean>
          再啟動看看,還是報錯
          org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'txAdvice': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' is defined
          原來是transactionManager的問題,在DAO里面將transactionManager注冊成osgi service,在domain.logic里面引用,然后給txAdvice加上transaction-manager屬性
          <tx:advice id="txAdvice" transaction-manager="transactionManagerOsgi">
                  
          <tx:attributes>
                      
          <tx:method name="insert*"/>
                      
          <tx:method name="update*"/>
                      
          <tx:method name="*" read-only="true"/>
                  
          </tx:attributes>
              
          </tx:advice>
          OK,啟動,正常了
           
          (三)petstore-servlet.xml
          最后到spring-mvc的配置文件了,在前面已經將這個配置文件拷貝到org.phrancol.osgi.jpetstore.springmvc/META-INF/dispatcher目錄下了,并且做了一些修改,讓DispatcherServlet加載用以顯示首頁
          1,新建一個package org.phrancol.osgi.jpetstore.springmvc.controller,將jpetstore\src\org\springframework\samples\jpetstore\web\spring里面的java文件拷貝進去,將依賴包導入,然后在petstore-servlet.xml里面加上一個dispatch-bean,
          <bean name="/shop/addItemToCart.do" class="org.phrancol.osgi.jpetstore.springmvc.controller.AddItemToCartController">
                  
          <property name="petStore" ref="petStore"/>
              
          </bean>
          啟動看看效果,報錯
          Caused by: java.lang.ClassNotFoundException: org.phrancol.osgi.jpetstore.springmvc.controller.AddItemToCartController
          居然找不到這個類,來看看ClassLoader
          Thread.currentThread().getContextClassLoader() -> org.eclipse.core.runtime.internal.adaptor.ContextFinder
          Activator
          's ClassLoader -> org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader
          原來如此,那就這樣
          Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader())
          其實這樣也是可以的,但是為了不繞彎路,而且既然是Spring的配置文件,Spring-osgi也提供得有Bundle的ClassLoader -> org.springframework.osgi.context.support.BundleDelegatingClassLoader 交給Spring的ClassLoader吧
          2,看一段代碼 org.springframework.osgi.context.support.BundleContextAwareProcessor
          public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
                  
          if (bean instanceof BundleContextAware) {
                      
          if (this.bundleContext == null{
                          
          throw new IllegalStateException("Cannot satisfy BundleContextAware for bean '" +
                                  beanName 
          + "' without BundleContext");
                      }

                      
          if (logger.isDebugEnabled()) {
                          logger.debug(
          "Invoking setBundleContext on BundleContextAware bean '" + beanName + "'");
                      }

                      ((BundleContextAware) bean).setBundleContext(
          this.bundleContext);
                  }

                  
          return true;
              }

          3,再來看看這個接口org.springframework.osgi.context.BundleContextAware
          Interface that enables beans to find the bundle context they are defined in. Note that in most circumstances there is no need for a bean to implement this interface
          OK,那就寫個BundleContextAware,然后配置成Bean就可以了

          4,創建一個 Plug-in project   org.phrancol.osgi.jpetstore.util,并創建同名package,新建一個Interface HttpServiceRegister 用于注冊Servlet或Resource,這個過程在方法 public void serviceRegister(BundleContext context);里進行,新建一個Class  BundleServiceRegister
          public class BundleServiceRegister implements BundleContextAware {
              
              
          private HttpServiceRegister httpServiceRegister;
              
              
          public BundleServiceRegister(HttpServiceRegister httpServiceRegister){
                  
          this.httpServiceRegister = httpServiceRegister;
              }


              
          public void setBundleContext(BundleContext context) {
                  
          this.httpServiceRegister.serviceRegister(context);
              }

          }

          5,生成一個類org.phrancol.osgi.jpetstore.springmvc.SpringmvcHttpServiceRegister implements HttpServiceRegister
          將Activator.start方法里的內容拷貝到SpringmvcHttpServiceRegister.serviceRegister方法里,刪除Activator(MANIFEST.MF)

          6,在org.phrancol.osgi.jpetstore.springmvc/META-INF/下建立一個目錄spring,從別的地方copy一個bean配置文件過來,改名為logic-context.xml,加入如下配置
          <beans>
              
          <bean id="springHttpServiceRegister"
                  class
          ="org.phrancol.osgi.jpetstore.util.BundleServiceRegister">
                  
          <constructor-arg>
                      
          <bean class="org.phrancol.osgi.jpetstore.springmvc.SpringmvcHttpServiceRegister" />
                  
          </constructor-arg>
              
          </bean>
          </beans>
          啟動,報錯,petstore-servlet.xml里面的bean petStore 找不到,這個bean被定義在org.phrancol.osgi.jpetstore.domain.logic里面,于是使用<osgi:service>和<osgi:reference>來獲取
          在logic-context-osgi.xml里面加上
          <osgi:service id="petStoreOsgi" ref="petStore"
                  interface
          ="org.phrancol.osgi.jpetstore.domain.logic.PetStoreFacade">
              
          </osgi:service>
          在springmvc-context.xml加入如下內容(注意namespaces)
              <osgi:reference id="petStoreOsgi"
                  interface
          ="org.phrancol.osgi.jpetstore.domain.logic.PetStoreFacade" />
          修改一下petstore-servlet.xml
          <property name="petStore" ref="petStore"/>
          改成
          <property name="petStore" ref="petStoreOsgi"/>
          OK,這次應該沒問題了,啟動看看效果,還是報錯
          org.springframework.beans.factory.BeanCreationException: Error creating bean with name '/shop/addItemToCart.do' defined in ServletContext resource [/META-INF/dispatcher/petstore-servlet.xml]: Cannot resolve reference to bean 'petStoreOsgi' while setting bean property 'petStore'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'petStoreOsgi' is defined
          Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 
          'petStoreOsgi' is defined
              at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:
          353)
              at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:
          916)
              at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:
          243)
              at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:
          160)
              at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:
          261)
              at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:
          109)
              at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:
          1100)
          居然找不到petStoreOsgi這個bean......
          posted on 2007-09-07 10:26 Phrancol Yang 閱讀(3992) 評論(0)  編輯  收藏 所屬分類: OSGI
          主站蜘蛛池模板: 蒙阴县| 柳河县| 万全县| 昌黎县| 宁晋县| 建瓯市| 胶州市| 丰原市| 镇沅| 囊谦县| 交城县| 乌拉特中旗| 津南区| 木里| 自治县| 威信县| 钟山县| 建湖县| 车致| 阳江市| 吉林市| 且末县| 巩义市| 尖扎县| 嵊泗县| 永仁县| 曲阳县| 平和县| 仪陇县| 太谷县| 呼玛县| 凤山县| 桂平市| 綦江县| 册亨县| 内江市| 栾川县| 洪江市| 莱芜市| 岳西县| 行唐县|