沉睡森林@漂在北京

          本處文章除注明“轉載”外均為原創,轉載請注明出處。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            152 隨筆 :: 4 文章 :: 114 評論 :: 0 Trackbacks
          最簡單的rose配置:
          <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns
          ="http://maven.apache.org/POM/4.0.0"
              xsi:schemaLocation
          ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
              <modelVersion>4.0.0</modelVersion>
              <groupId>com.jiexi.demos</groupId>
              <artifactId>rose-demos</artifactId>
              <version>0.0.1-SNAPSHOT</version>
              <packaging>war</packaging>

              <dependencies>
                  <dependency>
                      <groupId>net.paoding</groupId>
                      <artifactId>paoding-rose</artifactId>
                      <version>1.0-SNAPSHOT</version>
                  </dependency>
                  
                  <dependency>
                      <groupId>log4j</groupId>
                      <artifactId>log4j</artifactId>
                      <version>1.2.15</version>
                      <exclusions>
                          <exclusion>
                              <artifactId>mail</artifactId>
                              <groupId>javax.mail</groupId>
                          </exclusion>
                          <exclusion>
                              <artifactId>jms</artifactId>
                              <groupId>javax.jms</groupId>
                          </exclusion>
                          <exclusion>
                              <artifactId>jmxtools</artifactId>
                              <groupId>com.sun.jdmk</groupId>
                          </exclusion>
                          <exclusion>
                              <artifactId>jmxri</artifactId>
                              <groupId>com.sun.jmx</groupId>
                          </exclusion>
                      </exclusions>
                  </dependency>
              </dependencies>
              

              <build>
                  <finalName>jeasyweb-framework</finalName>

                  <plugins>
                      <plugin>
                          <groupId>org.apache.maven.plugins</groupId>
                          <artifactId>maven-compiler-plugin</artifactId>
                          <configuration>
                              <source>1.6</source>
                              <target>1.6</target>
                              <encoding>UTF-8</encoding>
                          </configuration>
                      </plugin>

                      <plugin>
                          <groupId>org.mortbay.jetty</groupId>
                          <artifactId>maven-jetty-plugin</artifactId>
                          <version>6.1.26</version>
                          <configuration>
                              <contextPath>/</contextPath>
                              <scanIntervalSeconds>10</scanIntervalSeconds>
                              <stopKey>foo</stopKey>
                              <stopPort>9998</stopPort>
                          </configuration>
                          <executions>
                              <execution>
                                  <id>start-jetty</id>
                                  <phase>pre-integration-test</phase>
                                  <goals>
                                      <goal>run</goal>
                                  </goals>
                                  <configuration>
                                      <scanIntervalSeconds>0</scanIntervalSeconds>
                                      <daemon>true</daemon>
                                  </configuration>
                              </execution>  
                              <execution>
                                  <id>stop-jetty</id>
                                  <phase>post-integration-test</phase>
                                  <goals>
                                      <goal>stop</goal>
                                  </goals>
                              </execution>
                          </executions>
                      </plugin>
                  </plugins>
              </build>
          </project>


          <?xml version="1.0" encoding="utf-8"?>

          <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
              version
          ="2.4">
               

              <context-param>
                  <param-name>log4jConfigLocation</param-name>
                  <param-value>/WEB-INF/log4j.properties</param-value>
              </context-param>
           
              <listener>
                  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
              </listener>
               

              <filter>
                  <filter-name>roseFilter</filter-name>
                  <filter-class>net.paoding.rose.RoseFilter</filter-class>
              </filter>

              <filter-mapping>
                  <filter-name>roseFilter</filter-name>
                  <url-pattern>/*</url-pattern>
                  <dispatcher>REQUEST</dispatcher>
                  <dispatcher>FORWARD</dispatcher>
                  <dispatcher>INCLUDE</dispatcher>
              </filter-mapping>


          </web-app>


          package com.jiexi.demos.rose.controllers;

          import net.paoding.rose.web.annotation.Path;
          import net.paoding.rose.web.annotation.rest.Get;

          @Path("")
          public class IndexController {

              @Get("index")
              public String index() {
                  return "index";
              }

          }

          rose啟動到底做了那些工作:

             @Override
              protected final void initFilterBean() throws ServletException {
                  try {
                      
                      long startTime = System.currentTimeMillis();
                      
                      if (logger.isInfoEnabled()) {
                          logger.info("[init] call 'init/rootContext'");
                      }

                      if (logger.isDebugEnabled()) {
                          StringBuilder sb = new StringBuilder();
                          @SuppressWarnings("unchecked")
                          Enumeration<String> iter = getFilterConfig().getInitParameterNames();
                          while (iter.hasMoreElements()) {
                              String name = (String) iter.nextElement();
                              sb.append(name).append("='").append(getFilterConfig().getInitParameter(name))
                                      .append("'\n");
                          }
                          logger.debug("[init] parameters: " + sb);
                      }

                      WebApplicationContext rootContext = prepareRootApplicationContext();

                      if (logger.isInfoEnabled()) {
                          logger.info("[init] exits from 'init/rootContext'");
                          logger.info("[init] call 'init/module'");
                      }

                      // 識別 Rose 程序模塊
                      this.modules = prepareModules(rootContext);

                      if (logger.isInfoEnabled()) {
                          logger.info("[init] exits from 'init/module'");
                          logger.info("[init] call 'init/mappingTree'");
                      }

                      // 創建匹配樹以及各個結點的上的執行邏輯(Engine)
                      this.mappingTree = prepareMappingTree(modules);

                      if (logger.isInfoEnabled()) {
                          logger.info("[init] exits from 'init/mappingTree'");
                          logger.info("[init] exits from 'init'");
                      }

                      long endTime = System.currentTimeMillis();
                      
                      // 打印啟動信息
                      printRoseInfos(endTime -  startTime);

                      //
                  } catch (final Throwable e) {
                      StringBuilder sb = new StringBuilder(1024);
                      sb.append("[Rose-").append(RoseVersion.getVersion());
                      sb.append("@Spring-").append(SpringVersion.getVersion()).append("]:");
                      sb.append(e.getMessage());
                      logger.error(sb.toString(), e);
                      throw new NestedServletException(sb.toString(), e);
                  }
              }

          2大核心功能:


          功能1:
             /**
               * 創建最根級別的 ApplicationContext 對象,比如WEB-INF、WEB-INF/classes、
               * jar中的spring配置文件所組成代表的、整合為一個 ApplicationContext 對象
               * 
               * 
          @return
               * 
          @throws IOException
               
          */
              private WebApplicationContext prepareRootApplicationContext() throws IOException {

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/rootContext] starting ");
                  }

                  ApplicationContext oldRootContext = (ApplicationContext) getServletContext().getAttribute(
                          ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

                  // 如果web.xml配置使用了spring裝載root應用context  不可以
                  
          // roseFilter可能因為啟動失敗,在請求的時候容器還會嘗試重新啟動,此時rootContext可能已經存在,不要簡單地拋出異常
                  
          // 同時這樣留出了使用Listener作為init rose context的擴展機會
                  if (oldRootContext != null) {
                      if (oldRootContext.getClass() != RoseWebAppContext.class) {
                          throw new IllegalStateException(
                                  "Cannot initialize context because there is already a root application context present - "
                                          + "check whether you have multiple ContextLoader* definitions in your web.xml!");
                      }
                      if (logger.isInfoEnabled()) {
                          logger.info("[init/rootContext] the root context exists:" + oldRootContext);
                      }
                      return (RoseWebAppContext) oldRootContext;
                  }

                  RoseWebAppContext rootContext = new RoseWebAppContext(getServletContext(), load, false);

                  String contextConfigLocation = this.contextConfigLocation;
                  // 確認所使用的applicationContext配置
                  if (StringUtils.isBlank(contextConfigLocation)) {
                      String webxmlContextConfigLocation = getServletContext().getInitParameter(
                              "contextConfigLocation");
                      if (StringUtils.isBlank(webxmlContextConfigLocation)) {
                          contextConfigLocation = RoseWebAppContext.DEFAULT_CONFIG_LOCATION;
                      } else {
                          contextConfigLocation = webxmlContextConfigLocation;
                      }
                  }
                  rootContext.setConfigLocation(contextConfigLocation);
                  rootContext.setId("rose.root");
                  rootContext.refresh();

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/rootContext] exits");
                  }

                  /* enable: WebApplicationContextUtils.getWebApplicationContext() */
                  getServletContext().setAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, rootContext);

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/rootContext] Published rose.root WebApplicationContext ["
                              + rootContext + "] as ServletContext attribute with name ["
                              + ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
                  }

                  return rootContext;
              }


          首先通過new直接創建WebApplicationContext,然后將其作為參數繼續構建modules。可以看到參數contextConfigLocation的處理:
          String webxmlContextConfigLocation = getServletContext().getInitParameter(
                              "contextConfigLocation");
                      if (StringUtils.isBlank(webxmlContextConfigLocation)) {
                          contextConfigLocation = RoseWebAppContext.DEFAULT_CONFIG_LOCATION;
                      } else {
                          contextConfigLocation = webxmlContextConfigLocation;
                      }

          這里可以再web.xml里面定義參數,或者使用系統默認的參數:"/WEB-INF/applicationContext*.xml"

          而對于main/resources/applicationContext *.xml 或者jar包里面的applicationContext*.xml文件的讀取,是通過復寫XmlWebApplicationContext的方法實現的:
              @Override
              protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException,
                      IOException {
                  Resource[] configResources = getConfigResourcesThrows();
                  if (configResources != null) {
                      reader.loadBeanDefinitions(configResources);
                  }
                  String[] configLocations = getConfigLocations();
                  if (configLocations != null) {
                      for (int i = 0; i < configLocations.length; i++) {
                          reader.loadBeanDefinitions(configLocations[i]);
                      }
                  }
              }


          功能2:

              private List<Module> prepareModules(WebApplicationContext rootContext) throws Exception {
                  // 自動掃描識別web層資源,納入Rose管理
                  if (logger.isInfoEnabled()) {
                      logger.info("[init/mudule] starting ");
                  }

                  ModuleResourceProvider provider = moduleResourceProviderClass.newInstance();

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/module] using provider: " + provider);
                      logger.info("[init/module] call 'moduleResource': to find all module resources.");
                      logger.info("[init/module] load " + load);
                  }
                  List<ModuleResource> moduleResources = provider.findModuleResources(load);

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/mudule] exits 'moduleResource'");
                  }

                  ModulesBuilder modulesBuilder = modulesBuilderClass.newInstance();

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/module] using modulesBuilder: " + modulesBuilder);
                      logger.info("[init/module] call 'moduleBuild': to build modules.");
                  }

                  List<Module> modules = modulesBuilder.build(moduleResources, rootContext);

                  if (logger.isInfoEnabled()) {
                      logger.info("[init/module] exits from 'moduleBuild'");
                      logger.info("[init/mudule] found " + modules.size() + " modules.");
                  }

                  return modules;
              }

          rose在init時會讀取controllers里面的以Controller結尾的類,通過prepareModules功能實現的。
          這塊功能較復雜,涉及到*Controller,*Interceptor,*ErrorHandler,rose.properties,messages等的讀取配置。
          這塊功能具體實現了rose的約定大約配置的思想,默認讀取package的配置對應到不同的module中。





          posted on 2012-04-19 13:58 王總兵 閱讀(1026) 評論(0)  編輯  收藏 所屬分類: Other
          主站蜘蛛池模板: 宝山区| 枣强县| 襄垣县| 新邵县| 惠安县| 顺昌县| 温州市| 洛阳市| 肇州县| 桐柏县| 宁津县| 诏安县| 广灵县| 武宣县| 萍乡市| 华宁县| 江都市| 泸西县| 泰宁县| 思南县| 宜兰县| 田阳县| 山东| 乾安县| 潜江市| 阳高县| 青州市| 南充市| 凤山县| 水富县| 长宁县| 黄梅县| 随州市| 奉新县| 青阳县| 当涂县| 阿瓦提县| 山阴县| 南投县| 潮安县| 阿荣旗|