博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
rose分析
阅读量:6156 次
发布时间:2019-06-21

本文共 9485 字,大约阅读时间需要 31 分钟。

最简单的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中。

本文转自博客园沉睡森林@漂在北京的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
类似于SVN的文档内容差异对比工具winmerge
查看>>
Cause: java.sql.SQLException: The user specified as a definer ('root'@'%') does not exist
查看>>
quratz线程
查看>>
execnet: rapid multi-Python deployment
查看>>
windows修改3389端口
查看>>
关于JavaScript词法
查看>>
FreeSwitch中的会议功能(4)
查看>>
MySQL中创建用户分配权限(到指定数据库或者指定数据库表中)
查看>>
监控利器--nagios
查看>>
ubuntu安装和查看已安装
查看>>
通过ping检测网络故障的典型次序
查看>>
Android事件处理的两种模型
查看>>
忠诚的含义
查看>>
我的友情链接
查看>>
机器学习PartIII:测试算法和NFL定理
查看>>
Python开发
查看>>
DHCP服务介绍及Linux下DHCP服务的管理配置
查看>>
网络安全系列之八 Cookie注入(注入中转)
查看>>
DVWA系列之15 文件包含漏洞利用
查看>>
开源GIS之--移动GIS
查看>>