第一篇:典型相关分析SAS代码
data fit;input X1 X2 X3 X4 X5 Y1 Y2 Y3;cards;14651000 3446 98.8 2094.51 104.2 2555.14 2637.67 179.76 13985000 3339 113.8 2305.2233 133.8 2462.45 2670.99 161.74 15162900 3093 108.9 2494.6668 93.8 2831.87 3015.04 186 14275800 3084 99.6 2770.48 99.8 2957.2 2259.86 210.3 13966000 3040 101.6 3224.05 142.4 2767.25 2169.47 206.16 13947000 2978 112.4086 3690.34 123.8 2935 2307 218.36 14632000 2952 102.5 3980.44 79.1 3119.91 2332.38 232.33 14123200 2761 106.2 4543.41 97.9 3230.04 2344.04 241.53 14299300 2703 107.3469 5231.33 143.2 3195.12 2411.98 239.79 14849000 2644 111.3 6007.5498 90.8 3342.09 2466.6 252.5 15218000 2604 103.8 6790.899 97.2 3456.7 2471.53 261.34 15344000 2567 99 7565 95.7 3518 2360.31 266.29 run;ods rtf file='F:结果.doc';proccancorr data=fit all vprefix=YING vname='yingxiang' wprefix=CHAN wname='shengchan';var X1 X2 X3 X4 X5;with Y1 Y2 Y3;run;ods rtf close;
第二篇:SAS如何实现典型相关分析
SAS实现典型相关分析
data ex20_1(type=corr);input _name_$3.x1 x2 y1-y4;_type_='corr';cards;x1 1.0 0.8491 0.5106 0.2497 0.5285 0.3019 x2 0.8491 1.0 0.8062 0.5438 0.7887 0.6064 y1 0.5106 0.8062 1.0 0.7833 0.9284 0.8364 y2 0.2497 0.5438 0.7833 1.0 0.6457 0.9051 y3 0.5285 0.7887 0.9284 0.6457 1.0 0.7097 y4 0.3019 0.6064 0.8364 0.9051 0.7097 1.0;proc cancorr edf=102;var x1 x2;with y1-y4;run;
data ex20_2(type=corr);input _name_$ x1-x9 y1-y5;_type_='corr';cards;x1 1-0.027 0.052 0.037 0.003 0.009-0.030 0.014 0.020 0.034 0.071 0.054-0.022 0.012 x2-0.027 1-0.065-0.057-0.016 0.014 0.053-0.080-0.067-0.023 0.019 0.046-0.034 0.012 x3 0.052-0.065 1 0.772 0.018 0.042-0.094 0.279 0.163 0.221 0.093-0.030 0.040-0.118 x4 0.037-0.057 0.772 1 0.003 0.044-0.080 0.098 0.040 0.224 0.116-0.013-0.013-0.096 x5 0.003-0.016 0.018 0.003 1-0.017-0.030 0.019 0.025-0.044-0.021 0.002-0.019 0.002 x6 0.009 0.014 0.042 0.044-0.017 1-0.020 0.009-0.018 0.032 0.047 0.009-0.037-0.015 x7-0.030 0.053-0.094-0.080-0.030-0.020 1-0.057 0.013 0.009-0.032 0.089 0.027 0.014 x8 0.014-0.080 0.279 0.098 0.019 0.009-0.057 1 0.447-0.018-0.036-0.031 0.156-0.041 x9 0.020-0.067 0.163 0.040 0.025-0.018 0.013 0.447 1-0.063-0.017-0.027 0.117-0.019 y1 0.034-0.023 0.221 0.224-0.044 0.032 0.009-0.018-0.063 1 0.156-0.070-0.070-0.116
y2 0.071 0.019 0.093 0.116-0.021 0.047-0.032-0.036-0.017 0.156 1-0.039-0.046-0.052 y3 0.054 0.046-0.030-0.013 0.002 0.009 0.089-0.031-0.027-0.070-0.039 1 0.001 0.013 y4-0.022-0.034 0.040-0.013-0.019-0.037 0.027 0.156 0.117-0.070-0.046 0.001 1-0.019 y5 0.012 0.012-0.118-0.096 0.002-0.015 0.014-0.041-0.019-0.116-0.052 0.013-0.019 1;proc cancorr data=ex20_2 edf=1494 red;var x1-x9;with y1-y5;run;
data ex21_1;input group num;do i=1 to num;input value@@;output;end;cards;1 25 6.5 13.5 12.8 6.2 13.9 14.7 9.5 9.0 6.9 16.8 13.3 10.8 12.2 14.9 13.7 12.8 5.3 11.8 12.4 7.6 13.3 11.9 11.2 12.3 12.7 0 20 8.5 6.4 4.6 1.7 9.7 5.3 4.9 5.7 3.8 6.5 6.3 5.4 3.3 4.7 8.6 6.3 5.9 4.8 4.5 5.2;proc logistic descending;model group=value/scale=none outroc=roc1;run;proc print;run;proc gplot;plot _SENSIT_*_1MSPEC_;run;
第三篇:典型相关分析的SAS实现
典型相关分析的SAS实现
data ex20_1(type=corr);input _name_$3.x1 x2 y1-y4;_type_='corr';cards;x1 1.0 0.8491 0.5106 0.2497 0.5285 0.3019 x2 0.8491 1.0 0.8062 0.5438 0.7887 0.6064 y1 0.5106 0.8062 1.0 0.7833 0.9284 0.8364 y2 0.2497 0.5438 0.7833 1.0 0.6457 0.9051 y3 0.5285 0.7887 0.9284 0.6457 1.0 0.7097 y4 0.3019 0.6064 0.8364 0.9051 0.7097 1.0;proc cancorr edf=102;var x1 x2;with y1-y4;run;
data ex20_2(type=corr);input _name_$ x1-x9 y1-y5;_type_='corr';cards;x1 1-0.027 0.052 0.037 0.003 0.009-0.030 0.014 0.020 0.034 0.071 0.054-0.022 0.012 x2-0.027 1-0.065-0.057-0.016 0.014 0.053-0.080-0.067-0.023 0.019 0.046-0.034 0.012 x3 0.052-0.065 1 0.772 0.018 0.042-0.094 0.279 0.163 0.221 0.093-0.030 0.040-0.118 x4 0.037-0.057 0.772 1 0.003 0.044-0.080 0.098 0.040 0.224 0.116-0.013-0.013-0.096 x5 0.003-0.016 0.018 0.003 1-0.017-0.030 0.019 0.025-0.044-0.021 0.002-0.019 0.002 x6 0.009 0.014 0.042 0.044-0.017 1-0.020 0.009-0.018 0.032 0.047 0.009-0.037-0.015 x7-0.030 0.053-0.094-0.080-0.030-0.020 1-0.057 0.013 0.009-0.032 0.089 0.027 0.014 x8 0.014-0.080 0.279 0.098 0.019 0.009-0.057 1 0.447-0.018-0.036-0.031 0.156-0.041 x9 0.020-0.067 0.163 0.040 0.025-0.018 0.013 0.447 1-0.063-0.017-0.027 0.117-0.019 y1 0.034-0.023 0.221 0.224-0.044 0.032 0.009-0.018-0.063 1 0.156-0.070-0.070-0.116
y2 0.071 0.019 0.093 0.116-0.021 0.047-0.032-0.036-0.017 0.156 1-0.039-0.046-0.052 y3 0.054 0.046-0.030-0.013 0.002 0.009 0.089-0.031-0.027-0.070-0.039 1 0.001 0.013 y4-0.022-0.034 0.040-0.013-0.019-0.037 0.027 0.156 0.117-0.070-0.046 0.001 1-0.019 y5 0.012 0.012-0.118-0.096 0.002-0.015 0.014-0.041-0.019-0.116-0.052 0.013-0.019 1;proc cancorr data=ex20_2 edf=1494 red;var x1-x9;with y1-y5;run;
data ex21_1;input group num;do i=1 to num;input value@@;output;end;cards;1 25 6.5 13.5 12.8 6.2 13.9 14.7 9.5 9.0 6.9 16.8 13.3 10.8 12.2 14.9 13.7 12.8 5.3 11.8 12.4 7.6 13.3 11.9 11.2 12.3 12.7 0 20 8.5 6.4 4.6 1.7 9.7 5.3 4.9 5.7 3.8 6.5 6.3 5.4 3.3 4.7 8.6 6.3 5.9 4.8 4.5 5.2;proc logistic descending;model group=value/scale=none outroc=roc1;run;proc print;run;proc gplot;plot _SENSIT_*_1MSPEC_;run;
第四篇:struts2代码分析
1.Struts2架构图和请求处理流程
请求首先通过Filter chain,Filter主要包括ActionContextCleanUp,它主要清理当前线程的ActionContext和Dispatcher;FilterDispatcher主要通过AcionMapper来决定需要调用哪个Action。
ActionMapper取得了ActionMapping后,在Dispatcher的serviceAction方法里创建ActionProxy,ActionProxy创建ActionInvocation,然后ActionInvocation调用Interceptors,执行Action本身,创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。
2.Struts2部分类介绍
这部分从Struts2参考文档中翻译就可以了。
ActionMapper
ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等java Servlet类的依赖。Struts2中它的默认实现类是DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式,它自己也有Restful的实现,具体可以参考文档的docs¥actionmapper.html。
ActionProxy&ActionInvocation
Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默认实现DefaultActionProxy是由ActionInvocation持有Action实例。ActionProxy作用是如何取得Action,无论是本地还是远程。而ActionInvocation的作用是如何执行Action,拦截器的功能就是在ActionInvocation中实现的。
ConfigurationProvider&Configuration
ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主要是尤其实现类XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider来解析。
3.Struts2请求流程
1、客户端发送请求
2、请求先通过ActionContextCleanUp-->FilterDispatcher
3、FilterDispatcher通过ActionMapper来决定这个Request需要调用哪个Action
4、如果ActionMapper决定调用某个Action,FilterDispatcher把请求的处理交给ActionProxy,这儿已经转到它的Delegate--Dispatcher来执行
5、ActionProxy根据ActionMapping和ConfigurationManager找到需要调用的Action类
6、ActionProxy创建一个ActionInvocation的实例
7、ActionInvocation调用真正的Action,当然这涉及到相关拦截器的调用
8、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现。
首先强调一下struts2的线程程安全,在Struts2中大量采用ThreadLocal线程局部变量的方法来保证线程的安全,像Dispatcher等都是通过ThreadLocal来保存变量值,使得每个线程都有自己独立的实例变量,互不相干.接下来就从Dispatcher开始看起,先看其构造函数:
//创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方
public Dispatcher(ServletContext servletContext, Map
this.servletContext = servletContext;
//配置在web.xml中的param参数
this.initParams = initParams;
}
//创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方
public Dispatcher(ServletContext servletContext, Map
this.servletContext = servletContext;
//配置在web.xml中的param参数
this.initParams = initParams;
}
我们再看在FilterDispatcher创建Dispatcher的:
protected Dispatcher createDispatcher(FilterConfig filterConfig){
Map
for(Enumeration e = filterConfig.getInitParameterNames();e.hasMoreElements();){
String name =(String)e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
都可以从FilterConfig中得到
return new Dispatcher(filterConfig.getServletContext(), params);
}
protected Dispatcher createDispatcher(FilterConfig filterConfig){
Map
for(Enumeration e = filterConfig.getInitParameterNames();e.hasMoreElements();){
String name =(String)e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
都可以从FilterConfig中得到
return new Dispatcher(filterConfig.getServletContext(), params);
}
分七步载入各种配置属性,都是通过ConfigurationProvider接口进行的,这个接口提供init(),destroy(),register()等方法.将各种ConfigurationProvider初始化之后将实例添加到ConfigurationManager的List里面.最后通过循环调用List里的这些destroy(),register()等方法实现对配置文件的属性进行注册和销毁等功能.下面将分析这七层功夫是怎样一步步练成的.首先是init_DefaultProperties()
创建Dispatcher之后,来看init()方法
init()方法是用来Load用户配置文件,资源文件以及默认的配置文件.主要分七步走,看下面注释
public void init(){
if(configurationManager == null){
//设置ConfigurationManager的defaultFrameworkBeanName.//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等
configurationManager
=
new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
//读取properties信息,默认的default.properties,init_DefaultProperties();// [1]
//读取xml配置文件
init_TraditionalXmlConfigurations();// [2]
//读取用户自定义的struts.properties
init_LegacyStrutsProperties();// [3]
//自定义的configProviders
init_CustomConfigurationProviders();// [5]
//载入FilterDispatcher传进来的initParams
init_FilterInitParameters();// [6]
//将配置文件中的bean与具体的类映射
init_AliasStandardObjects();// [7]
//构建一个用于依赖注射的Container对象
//在这里面会循环调用上面七个ConfigurationProvider的register方法
//其中的重点就是DefaultConfiguration的#reload()方法
Container container = init_PreloadConfiguration();
container.inject(this);
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
if(!dispatcherListeners.isEmpty()){
for(DispatcherListener l : dispatcherListeners){
l.dispatcherInitialized(this);
}
}
}
public void init(){
if(configurationManager == null){
//设置ConfigurationManager的defaultFrameworkBeanName.//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等
configurationManager
=
new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
//读取properties信息,默认的default.properties,init_DefaultProperties();// [1]
//读取xml配置文件
init_TraditionalXmlConfigurations();// [2]
//读取用户自定义的struts.properties
init_LegacyStrutsProperties();// [3]
//自定义的configProviders
init_CustomConfigurationProviders();// [5]
//载入FilterDispatcher传进来的initParams
init_FilterInitParameters();// [6]
//将配置文件中的bean与具体的类映射
init_AliasStandardObjects();// [7]
//构建一个用于依赖注射的Container对象
//在这里面会循环调用上面七个ConfigurationProvider的register方法
//其中的重点就是DefaultConfiguration的#reload()方法
Container container = init_PreloadConfiguration();
container.inject(this);
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
if(!dispatcherListeners.isEmpty()){
for(DispatcherListener l : dispatcherListeners){
l.dispatcherInitialized(this);
}
}
}
分七步载入各种配置属性,都是通过ConfigurationProvider接口进行的,这个接口提供init(),destroy(),register()等方法.将各种ConfigurationProvider初始化之后将实例添加到ConfigurationManager的List里面.最后通过循环调用List里的这些destroy(),register()等方法实现对配置文件的属性进行注册和销毁等功能.下面将分析这七层功夫是怎样一步步练成的.首先是init_DefaultProperties()
private void init_DefaultProperties(){
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}
接来看DefaultPropertiesProvider好了,DefaultPropertiesProvider实际上只是实现了register()方法
public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
Settings defaultSettings = null;
try {
defaultSettings = new PropertiesSettings(“org/apache/struts2/default”);
} catch(Exception e){
throw
}
loadSettings(props, defaultSettings);
}
private void init_DefaultProperties(){
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}
接来看DefaultPropertiesProvider好了,DefaultPropertiesProvider实际上只是实现了register()方法
public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
Settings defaultSettings = null;
try {
defaultSettings = new PropertiesSettings(“org/apache/struts2/default”);
} catch(Exception e){
new
ConfigurationException(“Could
not
find
or
error
in org/apache/struts2/default.properties”, e);
throw
}
new ConfigurationException(“Could not find or error in org/apache/struts2/default.properties”, e);
loadSettings(props, defaultSettings);
}
//PropertiesSettings构造方法
//读取org/apache/struts2/default.properties的配置信息,如果项目中需要覆盖,可以在classpath里的struts.properties里覆写
public PropertiesSettings(String name){
URL settingsUrl = ClassLoaderUtils.getResource(name + “.properties”, getClass());
if(settingsUrl == null){
LOG.debug(name + “.properties missing”);
settings = new LocatableProperties();
return;
}
settings
// Load settings
InputStream in = null;
try {
in = settingsUrl.openStream();
settings.load(in);
} catch(IOException e){
throw new StrutsException(“Could not load ” + name + “.properties:” + e, e);
} finally {
if(in!= null){
try {
=
new
LocatableProperties(new
LocationImpl(null, settingsUrl.toString()));
in.close();
} catch(IOException io){
LOG.warn(“Unable to close input stream”, io);
}
}
}
}
//loadSettings主要是将progerty的value和Locale从上面PropertiesSettings中取得并存放到LocatableProperties props
//这个props是register的一个入参.protected void loadSettings(LocatableProperties props, final Settings settings){
// We are calling the impl methods to get around the single instance of Settings that is expected
for(Iterator i = settings.listImpl();i.hasNext();){
String name =(String)i.next();
props.setProperty(name, settings.getLocationImpl(name));
}
}
//PropertiesSettings构造方法
//读取org/apache/struts2/default.properties的配置信息,如果项目中需要覆盖,可以在classpath里的struts.properties里覆写
public PropertiesSettings(String name){
URL settingsUrl = ClassLoaderUtils.getResource(name + “.properties”, getClass());
if(settingsUrl == null){
LOG.debug(name + “.properties missing”);
settings = new LocatableProperties();
return;
}
settings =
new
LocatableProperties(new
LocationImpl(null, settingsUrl.toString()));
settings.getImpl(name),// Load settings
InputStream in = null;
try {
in = settingsUrl.openStream();
settings.load(in);
} catch(IOException e){
throw new StrutsException(“Could not load ” + name + “.properties:” + e, e);
} finally {
if(in!= null){
try {
in.close();
} catch(IOException io){
LOG.warn(“Unable to close input stream”, io);
}
}
}
}
//loadSettings主要是将progerty的value和Locale从上面PropertiesSettings中取得并存放到LocatableProperties props
//这个props是register的一个入参.protected void loadSettings(LocatableProperties props, final Settings settings){
// We are calling the impl methods to get around the single instance of Settings that is expected
for(Iterator i = settings.listImpl();i.hasNext();){
String name =(String)i.next();
props.setProperty(name, settings.getLocationImpl(name));
}
}
再来看第二步:init_TraditionalXmlConfigurations()
private void init_TraditionalXmlConfigurations(){
settings.getImpl(name), //首先读取web.xml中的config初始参数值
//如果
没
有
配
置
就
使
用
默
认的DEFAULT_CONFIGURATION_PATHS:“struts-default.xml,struts-plugin.xml,struts.xml”,//这儿就可以看出为什么默认的配置文件必须取名为这三个名称了
//如果不想使用默认的名称,直接在web.xml中配置config初始参数即可
String configPaths = initParams.get(“config”);
if(configPaths == null){
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split(“¥¥s*[,]¥¥s*”);
for(String file : files){
if(file.endsWith(“.xml”)){
if(“xwork.xml”.equals(file)){
//XmlConfigurationProvider负责解析xwork.xml
configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
} else {
//其它xml都是由StrutsXmlConfigurationProvider来解析
configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException(“Invalid configuration file name”);
}
}
}
private void init_TraditionalXmlConfigurations(){
//首先读取web.xml中的config初始参数值
//如果
没
有
配
置
就
使
用
默
认的DEFAULT_CONFIGURATION_PATHS:“struts-default.xml,struts-plugin.xml,struts.xml”,//这儿就可以看出为什么默认的配置文件必须取名为这三个名称了
//如果不想使用默认的名称,直接在web.xml中配置config初始参数即可
String configPaths = initParams.get(“config”);
if(configPaths == null){
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split(“¥¥s*[,]¥¥s*”);
for(String file : files){
if(file.endsWith(“.xml”)){
if(“xwork.xml”.equals(file)){
//XmlConfigurationProvider负责解析xwork.xml
configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
} else {
//其它xml都是由StrutsXmlConfigurationProvider来解析
configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException(“Invalid configuration file name”);
}
}
}
对于其它配置文件只用接口。
类XmlConfigurationProvider负责配置文件的读取和解析,首先通过init()中的loadDocuments(configFileName);利用DomHelper中的
public static Document parse(InputSource inputSource, Map
addAction()方法负责读取
loadInterceptorStack()方法负责将
StrutsXmlConfigurationProvider,此类继承XmlConfigurationProvider,而XmlConfigurationProvider又实现ConfigurationProviderloadInterceptorStacks()方法负责将
而上面的方法最终会被addPackage()方法调用,addPackage又会被Provider的loadPackages()调用,将所读取到的数据汇集到PackageConfig对象中。
protected PackageConfig
addPackage(Element
packageElement)
throws ConfigurationException {
PackageConfig.Builder newPackage = buildPackageContext(packageElement);
if(newPackage.isNeedsRefresh()){
return newPackage.build();
}
// add result types(and default result)to this package
addResultTypes(newPackage, packageElement);
// load the interceptors and interceptor stacks for this package
loadInterceptors(newPackage, packageElement);
// load the default interceptor reference for this package
loadDefaultInterceptorRef(newPackage, packageElement);
// load the default class ref for this package
loadDefaultClassRef(newPackage, packageElement);
// load the global result list for this package
loadGlobalResults(newPackage, packageElement);
// load the global exception handler list for this package
loadGobalExceptionMappings(newPackage, packageElement);
// get actions
NodeList actionList = packageElement.getElementsByTagName(“action”);
for(int i = 0;i < actionList.getLength();i++){
Element actionElement =(Element)actionList.item(i);
addAction(actionElement, newPackage);
}
// load the default action reference for this package
loadDefaultActionRef(newPackage, packageElement);
PackageConfig cfg = newPackage.build();
configuration.addPackageConfig(cfg.getName(), cfg);
return cfg;
}
loadConfigurationFiles解析读取xml中的内容
private List
loadConfigurationFiles(String
fileName,Element includeElement){
...//通过DomHelper调用SAX进行解析xml
doc = DomHelper.parse(in, dtdMappings);
...Element rootElement = doc.getDocumentElement();
NodeList children = rootElement.getChildNodes();
int childSize = children.getLength();
for(int i = 0;i < childSize;i++){
Node childNode = children.item(i);
if(childNode instanceof Element){
Element child =(Element)childNode;
final String nodeName = child.getNodeName();
if(“include”.equals(nodeName)){
String includeFileName = child.getAttribute(“file”);
//解析每个action配置是,对于include文件可以使用通配符*来进行配置
//如Struts.xml中可配置成
if(includeFileName.indexOf('*')!=-1){
ClassPathFinder wildcardFinder = new ClassPathFinder();
wildcardFinder.setPattern(includeFileName);
Vector
for(String match : wildcardMatches){
//递归Load子file中的
docs.addAll(loadConfigurationFiles(match, child));
}
} else {
docs.addAll(loadConfigurationFiles(includeFileName, child));
}
}
}
}
docs.add(doc);
loadedFileUrls.add(url.toString());
...return docs;
}
首先强调一下struts2的线程程安全,在Struts2中大量采用ThreadLocal线程局部变量的方法来保证线程的安全,像Dispatcher等都是通过ThreadLocal来保存变量值,使得每个线程都有自己独立的实例变量,互不相干.接下来就从Dispatcher开始看起,先看其构造函数:
//创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方
public Dispatcher(ServletContext servletContext, Map
this.servletContext = servletContext;
//配置在web.xml中的param参数
this.initParams = initParams;
}
//创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方
public Dispatcher(ServletContext servletContext, Map
this.servletContext = servletContext;
//配置在web.xml中的param参数
this.initParams = initParams;
}
我们再看在FilterDispatcher创建Dispatcher的:
protected Dispatcher createDispatcher(FilterConfig filterConfig){
Map
for(Enumeration e = filterConfig.getInitParameterNames();e.hasMoreElements();){
String name =(String)e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
都可以从FilterConfig中得到
return new Dispatcher(filterConfig.getServletContext(), params);
}
protected Dispatcher createDispatcher(FilterConfig filterConfig){
Map
for(Enumeration e = filterConfig.getInitParameterNames();e.hasMoreElements();){
String name =(String)e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
都可以从FilterConfig中得到
return new Dispatcher(filterConfig.getServletContext(), params);
}
分七步载入各种配置属性,都是通过ConfigurationProvider接口进行的,这个接口提供init(),destroy(),register()等方法.将各种ConfigurationProvider初始化之后将实例添加到ConfigurationManager的List里面.最后通过循环调用List里的这些destroy(),register()等方法实现对配置文件的属性进行注册和销毁等功能.下面将分析这七层功夫是怎样一步步练成的.首先是init_DefaultProperties()
创建Dispatcher之后,来看init()方法
init()方法是用来Load用户配置文件,资源文件以及默认的配置文件.主要分七步走,看下面注释
public void init(){
if(configurationManager == null){
//设置ConfigurationManager的defaultFrameworkBeanName.//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等
configurationManager = ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
//读取properties信息,默认的default.properties,init_DefaultProperties();// [1]
//读取xml配置文件
init_TraditionalXmlConfigurations();// [2]
//读取用户自定义的struts.properties
init_LegacyStrutsProperties();// [3]
//自定义的configProviders
init_CustomConfigurationProviders();// [5]
//载入FilterDispatcher传进来的initParams
init_FilterInitParameters();// [6]
//将配置文件中的bean与具体的类映射
init_AliasStandardObjects();// [7]
//构建一个用于依赖注射的Container对象
//在这里面会循环调用上面七个ConfigurationProvider的register方法
//其中的重点就是DefaultConfiguration的#reload()方法
Container container = init_PreloadConfiguration();
container.inject(this);
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
if(!dispatcherListeners.isEmpty()){
for(DispatcherListener l : dispatcherListeners){
l.dispatcherInitialized(this);
}
}
new
}
public void init(){
if(configurationManager == null){
//设置ConfigurationManager的defaultFrameworkBeanName.//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等
configurationManager = ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
//读取properties信息,默认的default.properties,init_DefaultProperties();// [1]
//读取xml配置文件
init_TraditionalXmlConfigurations();// [2]
//读取用户自定义的struts.properties
init_LegacyStrutsProperties();// [3]
//自定义的configProviders
init_CustomConfigurationProviders();// [5]
//载入FilterDispatcher传进来的initParams
init_FilterInitParameters();// [6]
//将配置文件中的bean与具体的类映射
init_AliasStandardObjects();// [7]
//构建一个用于依赖注射的Container对象
//在这里面会循环调用上面七个ConfigurationProvider的register方法
//其中的重点就是DefaultConfiguration的#reload()方法
Container container = init_PreloadConfiguration();
container.inject(this);
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
if(!dispatcherListeners.isEmpty()){
for(DispatcherListener l : dispatcherListeners){
l.dispatcherInitialized(this);
}
}
new
}
分七步载入各种配置属性,都是通过ConfigurationProvider接口进行的,这个接口提供init(),destroy(),register()等方法.将各种ConfigurationProvider初始化之后将实例添加到ConfigurationManager的List里面.最后通过循环调用List里的这些destroy(),register()等方法实现对配置文件的属性进行注册和销毁等功能.下面将分析这七层功夫是怎样一步步练成的.首先是init_DefaultProperties()
private void init_DefaultProperties(){
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}
接来看DefaultPropertiesProvider好了,DefaultPropertiesProvider实际上只是实现了register()方法
public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
Settings defaultSettings = null;
try {
defaultSettings = new PropertiesSettings(“org/apache/struts2/default”);
} catch(Exception e){
throw
}
loadSettings(props, defaultSettings);
}
private void init_DefaultProperties(){
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}
接来看DefaultPropertiesProvider好了,DefaultPropertiesProvider实际上只是实现了new
ConfigurationException(“Could
not
find
or
error
in org/apache/struts2/default.properties”, e);
register()方法
public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
Settings defaultSettings = null;
try {
defaultSettings = new PropertiesSettings(“org/apache/struts2/default”);
} catch(Exception e){
throw
}
loadSettings(props, defaultSettings);
}
//PropertiesSettings构造方法
//读取org/apache/struts2/default.properties的配置信息,如果项目中需要覆盖,可以在classpath里的struts.properties里覆写
public PropertiesSettings(String name){
URL settingsUrl = ClassLoaderUtils.getResource(name + “.properties”, getClass());
if(settingsUrl == null){
LOG.debug(name + “.properties missing”);
settings = new LocatableProperties();
return;
}
settings
// Load settings
InputStream in = null;
try {
=
new
LocatableProperties(new
LocationImpl(null, settingsUrl.toString()));
new
ConfigurationException(“Could
not
find
or
error
in org/apache/struts2/default.properties”, e);
in = settingsUrl.openStream();
settings.load(in);
} catch(IOException e){
throw new StrutsException(“Could not load ” + name + “.properties:” + e, e);
} finally {
if(in!= null){
try {
in.close();
} catch(IOException io){
LOG.warn(“Unable to close input stream”, io);
}
}
}
}
//loadSettings主要是将progerty的value和Locale从上面PropertiesSettings中取得并存放到LocatableProperties props
//这个props是register的一个入参.protected void loadSettings(LocatableProperties props, final Settings settings){
// We are calling the impl methods to get around the single instance of Settings that is expected
for(Iterator i = settings.listImpl();i.hasNext();){
String name =(String)i.next();
props.setProperty(name, settings.getLocationImpl(name));
}
}
//PropertiesSettings构造方法
//读取org/apache/struts2/default.properties的配置信息,如果项目中需要覆盖,可以在classpath里的struts.properties里覆写
public PropertiesSettings(String name){
URL settingsUrl = ClassLoaderUtils.getResource(name + “.properties”, getClass());
settings.getImpl(name),if(settingsUrl == null){
LOG.debug(name + “.properties missing”);
settings = new LocatableProperties();
return;
}
settings
// Load settings
InputStream in = null;
try {
in = settingsUrl.openStream();
settings.load(in);
} catch(IOException e){
throw new StrutsException(“Could not load ” + name + “.properties:” + e, e);
} finally {
if(in!= null){
try {
in.close();
} catch(IOException io){
LOG.warn(“Unable to close input stream”, io);
}
}
}
}
//loadSettings主要是将progerty的value和Locale从上面PropertiesSettings中取得并存放到LocatableProperties props
//这个props是register的一个入参.protected void loadSettings(LocatableProperties props, final Settings settings){
// We are calling the impl methods to get around the single instance of Settings that is expected
for(Iterator i = settings.listImpl();i.hasNext();){
String name =(String)i.next();
=
new
LocatableProperties(new
LocationImpl(null, settingsUrl.toString()));
props.setProperty(name, settings.getLocationImpl(name));
}
}
再来看第二步:init_TraditionalXmlConfigurations()
private void init_TraditionalXmlConfigurations(){
//首先读取web.xml中的config初始参数值
//如果
没
有
配
置
就
使
settings.getImpl(name),用默认的DEFAULT_CONFIGURATION_PATHS:“struts-default.xml,struts-plugin.xml,struts.xml”,//这儿就可以看出为什么默认的配置文件必须取名为这三个名称了
//如果不想使用默认的名称,直接在web.xml中配置config初始参数即可
String configPaths = initParams.get(“config”);
if(configPaths == null){
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split(“¥¥s*[,]¥¥s*”);
for(String file : files){
if(file.endsWith(“.xml”)){
if(“xwork.xml”.equals(file)){
//XmlConfigurationProvider负责解析xwork.xml
configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
} else {
//其它xml都是由StrutsXmlConfigurationProvider来解析
configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException(“Invalid configuration file name”);
}
}
}
private void init_TraditionalXmlConfigurations(){
//首先读取web.xml中的config初始参数值
//如果
没
有
配
置
就
使
用
默
认的DEFAULT_CONFIGURATION_PATHS:“struts-default.xml,struts-plugin.xml,struts.xml”,//这儿就可以看出为什么默认的配置文件必须取名为这三个名称了
//如果不想使用默认的名称,直接在web.xml中配置config初始参数即可
String configPaths = initParams.get(“config”);
if(configPaths == null){
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split(“¥¥s*[,]¥¥s*”);
for(String file : files){
if(file.endsWith(“.xml”)){
if(“xwork.xml”.equals(file)){
//XmlConfigurationProvider负责解析xwork.xml
configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
} else {
//其它xml都是由StrutsXmlConfigurationProvider来解析
configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException(“Invalid configuration file name”);
}
}
}
对于其它配置文件只用接口。
类XmlConfigurationProvider负责配置文件的读取和解析,首先通过init()中的loadDocuments(configFileName);利用DomHelper中的
public static Document parse(InputSource inputSource, Map
addAction()方法负责读取
loadInterceptorStack()方法负责将
loadInterceptorStacks()方法负责将
而上面的方法最终会被addPackage()方法调用,addPackage又会被Provider的loadPackages()调用,将所读取到的数据汇集到PackageConfig对象中。
protected PackageConfig
addPackage(Element
packageElement)
throws ConfigurationException {
PackageConfig.Builder newPackage = buildPackageContext(packageElement);
if(newPackage.isNeedsRefresh()){
return newPackage.build();
}
// add result types(and default result)to this package
addResultTypes(newPackage, packageElement);
// load the interceptors and interceptor stacks for this package
loadInterceptors(newPackage, packageElement);
// load the default interceptor reference for this package
loadDefaultInterceptorRef(newPackage, packageElement);
// load the default class ref for this package
loadDefaultClassRef(newPackage, packageElement);
// load the global result list for this package
loadGlobalResults(newPackage, packageElement);
// load the global exception handler list for this package
loadGobalExceptionMappings(newPackage, packageElement);
// get actions
NodeList actionList = packageElement.getElementsByTagName(“action”);
for(int i = 0;i < actionList.getLength();i++){
Element actionElement =(Element)actionList.item(i);
addAction(actionElement, newPackage);
}
// load the default action reference for this package
loadDefaultActionRef(newPackage, packageElement);
PackageConfig cfg = newPackage.build();
configuration.addPackageConfig(cfg.getName(), cfg);
return cfg;
}
loadConfigurationFiles解析读取xml中的内容
private List
loadConfigurationFiles(String
fileName, includeElement){
...//通过DomHelper调用SAX进行解析xml
doc = DomHelper.parse(in, dtdMappings);
...Element rootElement = doc.getDocumentElement();
NodeList children = rootElement.getChildNodes();
int childSize = children.getLength();
for(int i = 0;i < childSize;i++){
Node childNode = children.item(i);
if(childNode instanceof Element){
Element child =(Element)childNode;
final String nodeName = child.getNodeName();
if(“include”.equals(nodeName)){
String includeFileName = child.getAttribute(“file”);
//解析每个action配置是,对于include文件可以使用通配符*来进行配置
//如Struts.xml中可配置成
if(includeFileName.indexOf('*')!=-1){
ClassPathFinder wildcardFinder = new ClassPathFinder();
wildcardFinder.setPattern(includeFileName);
Element
Vector
for(String match : wildcardMatches){
//递归Load子file中的
docs.addAll(loadConfigurationFiles(match, child));
}
} else {
docs.addAll(loadConfigurationFiles(includeFileName, child));
}
}
}
}
docs.add(doc);
loadedFileUrls.add(url.toString());
...return docs;
}
接下来第三步:init_LegacyStrutsProperties()调用的是调用的是LegacyPropertiesConfigurationProvider 通过比较前
面
DefaultPropertiesProvider
与
调
用的是LegacyPropertiesConfigurationProvider.发现DefaultPropertiesProvider继承自后者,但重写了register()方法,主要是生成PropertiesSetting的不同,前者是根据org/apache/struts2/default.properties 后者是根据struts.properties 我们展开register()中的Settings.getInstance(),最后是调用getDefaultInstance()
private static Settings getDefaultInstance(){
if(defaultImpl == null){
// Create bootstrap implementation
//不带参数的DefaultSettings(),区别与DefaultPropertiesProvider中直接带default.properties参数
//不带参数就是默认为struts.propertes,并且加载struts.custom.properties所定义的properties文件
defaultImpl = new DefaultSettings();
// Create default implementation
try {
//STRUTS_CONFIGURATION为:struts.configuration
//在struts.proterties中查找struts.configuration的值,这个值必须是org.apache.struts2.config.Configuration接口的实现类
//所以我有个困惑就是在下面的转换当中怎么将Configuration转换成Setting类型的...//这一点先放下了,有时间再研究
String className = get(StrutsConstants.STRUTS_CONFIGURATION);
if(!className.equals(defaultImpl.getClass().getName())){
try {
// singleton instances shouldn't be built accessing request or session-specific context data
defaultImpl oader().loadClass(className), null);
} catch(Exception e){
LOG.error(“Settings:
}
}
} catch(IllegalArgumentException ex){
// ignore
}
private static Settings getDefaultInstance(){
if(defaultImpl == null){
// Create bootstrap implementation
//不带参数的DefaultSettings(),区别与DefaultPropertiesProvider中直接带default.properties参数
//不带参数就是默认为struts.propertes,并且加载struts.custom.properties所定义的properties文件
defaultImpl = new DefaultSettings();
// Create default implementation
try {
//STRUTS_CONFIGURATION为:struts.configuration
//在struts.proterties中查找struts.configuration的值,这个值必须是
Could
not
instantiate
the struts.configuration object, substituting the default implementation.”, e);
=
(Settings)ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLorg.apache.struts2.config.Configuration接口的实现类
//所以我有个困惑就是在下面的转换当中怎么将Configuration转换成Setting类型的...//这一点先放下了,有时间再研究
String className = get(StrutsConstants.STRUTS_CONFIGURATION);
if(!className.equals(defaultImpl.getClass().getName())){
try {
// singleton instances shouldn't be built accessing request or session-specific context data
defaultImpl oader().loadClass(className), null);
} catch(Exception e){
LOG.error(“Settings:
}
}
} catch(IllegalArgumentException ex){
// ignore
}
在2.1.6中去掉了第四步:init_ZeroConfiguration();第五步是自定义的configProviders
private void init_CustomConfigurationProviders(){
//从这里可以看到可以将自定义的Provider定义在web.xml中FilterDispatcher的param中:configProviders
String configProvs = initParams.get(”configProviders“);
if(configProvs!= null){
String[] classes = configProvs.split(”¥¥s*[,]¥¥s*“);
for(String cname : classes){
try {
Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
ConfigurationProvider(ConfigurationProvider)cls.newInstance();
configurationManager.addConfigurationProvider(prov);
prov
=
Could
not
instantiate
the struts.configuration object, substituting the default implementation.”, e);
=
(Settings)ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassL
}
...}
}
}
private void init_CustomConfigurationProviders(){
//从这里可以看到可以将自定义的Provider定义在web.xml中FilterDispatcher的param中:configProviders
String configProvs = initParams.get(“configProviders”);
if(configProvs!= null){
String[] classes = configProvs.split(“¥¥s*[,]¥¥s*”);
for(String cname : classes){
try {
Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
ConfigurationProvider(ConfigurationProvider)cls.newInstance();
configurationManager.addConfigurationProvider(prov);
}
...}
}
}
第六步:init_FilterInitParameters
//从这里可以看出struts.properties中的属性不仅可以在struts.xml中以constant形式定义,而且可以在FilterDispatcher的param中定义
private void init_FilterInitParameters(){
configurationManager.addConfigurationProvider(new ConfigurationProvider(){
public void destroy(){}
public
void
init(Configuration
configuration)
throws ConfigurationException {}
public void loadPackages()throws ConfigurationException {}
public boolean needsReload(){ return false;}
prov
=
public void register(ContainerBuilder builder, LocatableProperties props)throws ConfigurationException {
props.putAll(initParams);//在这里实现滴~
}
});
}
//从这里可以看出struts.properties中的属性不仅可以在struts.xml中以constant形式定义,而且可以在FilterDispatcher的param中定义
private void init_FilterInitParameters(){
configurationManager.addConfigurationProvider(new ConfigurationProvider(){
public void destroy(){}
public
void
init(Configuration
configuration)
throws ConfigurationException {}
public void loadPackages()throws ConfigurationException {}
public boolean needsReload(){ return false;}
public void register(ContainerBuilder builder, LocatableProperties props)throws ConfigurationException {
props.putAll(initParams);//在这里实现滴~
}
});
}
第七步:init_AliasStandardObjects,使用BeanSelectionProvider 这是将配置文件中定义的
接下来是看怎样调用这些ConfigurationProviders 展开init_PreloadConfiguration()
private Container init_PreloadConfiguration(){
Configuration config = configurationManager.getConfiguration();
Container container = config.getContainer();
boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));
LocalizedTextUtil.setReloadBundles(reloadi18n);
return container;
}
//再看getConfiguration()
public synchronized Configuration getConfiguration(){
if(configuration == null){
setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
try {
//重点就是这个reloadContainer
configuration.reloadContainer(getContainerProviders());
} catch(ConfigurationException e){
setConfiguration(null);
throw new ConfigurationException(“Unable to load configuration.”, e);
}
} else {
conditionalReload();
}
return configuration;
}
private Container init_PreloadConfiguration(){
Configuration config = configurationManager.getConfiguration();
Container container = config.getContainer();
boolean reloadi18n
=
Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));
LocalizedTextUtil.setReloadBundles(reloadi18n);
return container;
}
//再看getConfiguration()
public synchronized Configuration getConfiguration(){
if(configuration == null){
setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
try {
//重点就是这个reloadContainer
configuration.reloadContainer(getContainerProviders());
} catch(ConfigurationException e){
setConfiguration(null);
throw new ConfigurationException(“Unable to load configuration.”, e);
}
} else {
conditionalReload();
}
return configuration;
}
展开DefaultConfiguration中的reloadContainer
public synchronized List
reloadContainer(List
packageContexts.clear();
loadedFileNames.clear();
List
packageProviders = new ArrayList
();
//Struts2(xwork2)用Container来完成依赖注入的功能
//首先初始化一个ContainerBuilder,再由builder来保存接口与实现类或工厂类的对应关系
//然后通过builder.create(boolean)方法产生container
//由container.getInstance(Class);就可以得到接口的实现实例了
//这一部分比较复杂,后面研究完成了,会单独拿出来讲,这里先弄清楚Xwork依赖注入的实现步骤就可以了
ContainerProperties props = new ContainerProperties();
ContainerBuilder builder = new ContainerBuilder();
for(final ContainerProvider containerProvider : providers)
{
//循环调用ConfigurationProvider的init和register方法,明白了吧,在这里统一循环调用
containerProvider.init(this);
containerProvider.register(builder, props);
}
props.setConstants(builder);
//注入依赖关系,在这里并不产生实例
builder.factory(Configuration.class, new Factory
public Configuration create(Context context)throws Exception {
return DefaultConfiguration.this;
}
});
ActionContext oldContext = ActionContext.getContext();
try {
// Set the bootstrap container for the purposes of factory creation
Container bootstrap = createBootstrapContainer();
setContext(bootstrap);
//create已经注入依赖关系的Container
container = builder.create(false);
setContext(container);
objectFactory = container.getInstance(ObjectFactory.class);
// Process the configuration providers first
for(final ContainerProvider containerProvider : providers)
{
if(containerProvider instanceof PackageProvider){
container.inject(containerProvider);
//调用PackageProvider的loadPackages()方法,这里主要是针对XmlConfigurationProvider和StrutsXmlConfigurationProvider
((PackageProvider)containerProvider).loadPackages();
packageProviders.add((PackageProvider)containerProvider);
}
}
// Then process any package providers from the plugins
Set
packageProviderNames
= container.getInstanceNames(PackageProvider.class);
if(packageProviderNames!= null){
for(String name : packageProviderNames){
PackageProvider
provider.init(this);
provider.loadPackages();
packageProviders.add(provider);
}
}
rebuildRuntimeConfiguration();
} finally {
if(oldContext == null){
ActionContext.setContext(null);
}
}
return packageProviders;
}
Dispatcher已经在之前讲过,这就好办了。FilterDispatcher是Struts2的核心控制器,首先看一下init()方法。
public void init(FilterConfig filterConfig)throws ServletException {
try {
this.filterConfig = filterConfig;
initLogging();
//创建dispatcher,前面都已经讲过啰
dispatcher = createDispatcher(filterConfig);
dispatcher.init();
//注入将FilterDispatcher中的变量通过container注入,如下面的staticResourceLoader
dispatcher.getContainer().inject(this);
//StaticContentLoader在BeanSelectionProvider中已经被注入了依赖关系:DefaultStaticContentLoader
//可以在struts-default.xml中的
staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
} finally {
provider
= container.getInstance(PackageProvider.class, name);
ActionContext.setContext(null);
}
}
public void init(FilterConfig filterConfig)throws ServletException {
try {
this.filterConfig = filterConfig;
initLogging();
//创建dispatcher,前面都已经讲过啰
dispatcher = createDispatcher(filterConfig);
dispatcher.init();
//注入将FilterDispatcher中的变量通过container注入,如下面的staticResourceLoader
dispatcher.getContainer().inject(this);
//StaticContentLoader在BeanSelectionProvider中已经被注入了依赖关系:DefaultStaticContentLoader
//可以在struts-default.xml中的
staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
} finally {
ActionContext.setContext(null);
}
}
//下面来看DefaultStaticContentLoader的setHostConfig
public void setHostConfig(HostConfig filterConfig){
//读取初始参数
pakages,调用
parse(),解析成类似/org/apache/struts2/static,/template的数组
String param = filterConfig.getInitParameter(“packages”);
//“org.apache.struts2.static org.apache.struts2.interceptor.debugging static”
String packages = getAdditionalPackages();
if(param!= null){
packages = param + “ ” + packages;
}
this.pathPrefixes = parse(packages);
initLogging(filterConfig);
}
template //下面来看DefaultStaticContentLoader的setHostConfig
public void setHostConfig(HostConfig filterConfig){
//读取初始参数
pakages,调用
parse(),解析成类似/org/apache/struts2/static,/template的数组
String param = filterConfig.getInitParameter(“packages”);
//“org.apache.struts2.static org.apache.struts2.interceptor.debugging static”
String packages = getAdditionalPackages();
if(param!= null){
packages = param + “ ” + packages;
}
this.pathPrefixes = parse(packages);
initLogging(filterConfig);
}
现在回去doFilter的方法,每当有一个Request,都会调用这些Filters的doFilter方法
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest)req;
HttpServletResponse response =(HttpServletResponse)res;
ServletContext servletContext = getServletContext();
String timerKey = “FilterDispatcher_doFilter: ”;
try {
// FIXME: this should be refactored better to not duplicate work with the action invocation
//先看看ValueStackFactory所注入的实现类OgnlValueStackFactory
//new OgnlValueStack
ValueStack
stack
= dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
ActionContext ctx = new ActionContext(stack.getContext());
ActionContext.setContext(ctx);
template
UtilTimerStack.push(timerKey);
//如果是multipart/form-data就用MultiPartRequestWrapper进行包装
//MultiPartRequestWrapper
是
StrutsRequestWrapper的子类,两者都是HttpServletRequest实现
//此时在MultiPartRequestWrapper中就会把Files给解析出来,用于文件上传
//所有request都会StrutsRequestWrapper进行包装,StrutsRequestWrapper是可以访问ValueStack
//下面是参见Dispatcher的wrapRequest
// String content_type = request.getContentType();
//if(content_type!= null&&content_type.indexOf(“multipart/form-data”)!=-1){
//MultiPartRequest multi =getContainer().getInstance(MultiPartRequest.class);
//request MultiPartRequestWrapper(multi,request,getSaveDir(servletContext));
//} else {
//
request = new StrutsRequestWrapper(request);
// }
request = prepareDispatcherAndWrapRequest(request, response);
ActionMapping mapping;
try {
//根据url取得对应的Action的配置信息
//看一下注入的DefaultActionMapper的getMapping()方法.Action的配置信息存储在 ActionMapping对象中
mapping
=
actionMapper.getMapping(request, dispatcher.getConfigurationManager());
} catch(Exception ex){
log.error(“error getting ActionMapping”, ex);
dispatcher.sendError(request,return;
}
//如果找不到对应的action配置,则直接返回。比如你输入***.jsp等等
//这儿有个例外,就是如果path是以“/struts”开头,则到初始参数packages配置的包路径去查找对应的静态资源并输出到页面流中,当然.class文件除外。如果再没有则跳转到
response,servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
=new 404
if(mapping == null){
// there is no action in this request, should we look for a static resource?
String resourcePath = RequestUtils.getServletPath(request);
if(“".equals(resourcePath)&& null!= request.getPathInfo()){
resourcePath = request.getPathInfo();
}
if(staticResourceLoader.canHandle(resourcePath)){
// 在DefaultStaticContentLoader
中
:return
serveStatic
&&(resourcePath.startsWith(”/struts“)|| resourcePath.startsWith(”/static“));
staticResourceLoader.findStaticResource(resourcePath, response);
} else {
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// The framework did its job here
return;
}
//正式开始Action的方法
dispatcher.serviceAction(request, response, servletContext, mapping);
} finally {
try {
ActionContextCleanUp.cleanUp(req);
} finally {
UtilTimerStack.pop(timerKey);
}
}
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest)req;
request,HttpServletResponse response =(HttpServletResponse)res;
ServletContext servletContext = getServletContext();
String timerKey = ”FilterDispatcher_doFilter: “;
try {
// FIXME: this should be refactored better to not duplicate work with the action invocation
//先看看ValueStackFactory所注入的实现类OgnlValueStackFactory
//new OgnlValueStack
ValueStack
stack
= dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
ActionContext ctx = new ActionContext(stack.getContext());
ActionContext.setContext(ctx);
UtilTimerStack.push(timerKey);
//如果是multipart/form-data就用MultiPartRequestWrapper进行包装
//MultiPartRequestWrapperHttpServletRequest实现
//此时在MultiPartRequestWrapper中就会把Files给解析出来,用于文件上传
//所有request都会StrutsRequestWrapper进行包装,StrutsRequestWrapper是可以访问ValueStack
//下面是参见Dispatcher的wrapRequest
// String content_type = request.getContentType();
//if(content_type!= null&&content_type.indexOf(”multipart/form-data“)!=-1){
//MultiPartRequest multi =getContainer().getInstance(MultiPartRequest.class);
//request MultiPartRequestWrapper(multi,request,getSaveDir(servletContext));
//} else {
//
request = new StrutsRequestWrapper(request);
// }
request = prepareDispatcherAndWrapRequest(request, response);
ActionMapping mapping;
try {
=new
是
StrutsRequestWrapper的子类,两者都是
//根据url取得对应的Action的配置信息
//看一下注入的DefaultActionMapper的getMapping()方法.Action的配置信息存储在 ActionMapping对象中
mapping
} catch(Exception ex){
log.error(”error getting ActionMapping“, ex);
dispatcher.sendError(request,return;
}
//如果找不到对应的action配置,则直接返回。比如你输入***.jsp等等
//这儿有个例外,就是如果path是以“/struts”开头,则到初始参数packages配置的包路径去查找对应的静态资源并输出到页面流中,当然.class文件除外。如果再没有则跳转到404
if(mapping == null){
// there is no action in this request, should we look for a static resource?
String resourcePath = RequestUtils.getServletPath(request);
if(”“.equals(resourcePath)&& null!= request.getPathInfo()){
resourcePath = request.getPathInfo();
}
if(staticResourceLoader.canHandle(resourcePath)){
// 在DefaultStaticContentLoader
中
:return
serveStatic
&&(resourcePath.startsWith(”/struts“)|| resourcePath.startsWith(”/static“));
staticResourceLoader.findStaticResource(resourcePath, response);
} else {
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// The framework did its job here
return;
}
request,response,servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
=
actionMapper.getMapping(request, dispatcher.getConfigurationManager());
//正式开始Action的方法
dispatcher.serviceAction(request, response, servletContext, mapping);
} finally {
try {
ActionContextCleanUp.cleanUp(req);
} finally {
UtilTimerStack.pop(timerKey);
}
}
}
//下面是ActionMapper接口的实现类 DefaultActionMapper的getMapping()方法的源代码:
public ActionMapping getMapping(HttpServletRequest request,ConfigurationManager configManager){
ActionMapping mapping = new ActionMapping();
String uri = getUri(request);//得到请求路径的URI,如:testAtcion.action或testAction.do
int indexOfSemicolon = uri.indexOf(”;“);//修正url的带;jsessionid 时找不到而且的bug
uri =(indexOfSemicolon >-1)? uri.substring(0, indexOfSemicolon): uri;
uri = dropExtension(uri, mapping);//删除扩展名,默认扩展名为action
if(uri == null){
return null;
}
parseNameAndNamespace(uri, mapping, configManager);//匹配Action的name和namespace
handleSpecialParameters(request, mapping);//去掉重复参数
//如果Action的name没有解析出来,直接返回
if(mapping.getName()== null){
returnnull;
}
//下面处理形如testAction!method格式的请求路径
if(allowDynamicMethodCalls){
// handle ”name!method“ convention.String name = mapping.getName();
int exclamation = name.lastIndexOf(”!“);//!是Action名称和方法名的分隔符
if(exclamation!=-1){
mapping.setName(name.substring(0, exclamation));//提取左边为name
mapping.setMethod(name.substring(exclamation + 1));//提取右边的method
}
}
return mapping;
}
//下面是ActionMapper接口的实现类 DefaultActionMapper的getMapping()方法的源代码:
public ActionMapping getMapping(HttpServletRequest request,ConfigurationManager configManager){
ActionMapping mapping = new ActionMapping();
String uri = getUri(request);//得到请求路径的URI,如:testAtcion.action或testAction.do
int indexOfSemicolon = uri.indexOf(”;“);//修正url的带;jsessionid 时找不到而且的bug
uri =(indexOfSemicolon >-1)? uri.substring(0, indexOfSemicolon): uri;
uri = dropExtension(uri, mapping);//删除扩展名,默认扩展名为action
if(uri == null){
return null;
}
parseNameAndNamespace(uri, mapping, configManager);//匹配Action的name和namespace
handleSpecialParameters(request, mapping);//去掉重复参数
//如果Action的name没有解析出来,直接返回
if(mapping.getName()== null){
returnnull;
}
//下面处理形如testAction!method格式的请求路径
if(allowDynamicMethodCalls){
// handle ”name!method“ convention.String name = mapping.getName();
int exclamation = name.lastIndexOf(”!“);//!是Action名称和方法名的分隔符
if(exclamation!=-1){
mapping.setName(name.substring(0, exclamation));//提取左边为name
mapping.setMethod(name.substring(exclamation + 1));//提取右边的method
}
}
return mapping;
}
从代码中看出,getMapping()方法返回ActionMapping类型的对象,该对象包含三个参数:Action的name、namespace和要调用的方法method。
如果getMapping()方法返回ActionMapping对象为null,则FilterDispatcher认为用户请求不是Action,自然另当别论,FilterDispatcher会做一件非常有意思的事:如果请求以/struts开头,会自动查找在web.xml文件中配置的 packages初始化参数,就像下面这样:
org.apache.struts2.dispatcher.FilterDispatcher
packages
com.lizanhong.action
org.apache.struts2.dispatcher.FilterDispatcher
packages
com.lizanhong.action
FilterDispatcher会将com.lizanhong.action包下的文件当作静态资源处理,即直接在页面上显示文件内容,不过会忽略扩展名为class的文件。比如在com.lizanhong.action包下有一个aaa.txt的文本文件,其内容为“中华人民共和国”,访问
http://localhost:8081/Struts2Demo/struts/aaa.txt时会输出txt中的内容
FilterDispatcher.findStaticResource()方法
protectedvoid findStaticResource(String
name,HttpServletRequest
request, HttpServletResponse response)throws IOException {
if(!name.endsWith(”.class“)){//忽略class文件
//遍历packages参数
for(String pathPrefix : pathPrefixes){
InputStream is = findInputStream(name, pathPrefix);//读取请求文件流
if(is!= null){
...// set the content-type header
String contentType = getContentType(name);//读取内容类型
if(contentType!= null){
response.setContentType(contentType);//重新设置内容类型
}
...try {
//将读取到的文件流以每次复制4096个字节的方式循环输出
copy(is, response.getOutputStream());
} finally {
is.close();
}
return;
}
}
}
}
protectedvoid findStaticResource(String
name,HttpServletRequest
request, HttpServletResponse response)throws IOException {
if(!name.endsWith(”.class“)){//忽略class文件
//遍历packages参数
for(String pathPrefix : pathPrefixes){
InputStream is = findInputStream(name, pathPrefix);//读取请求文件流
if(is!= null){
...// set the content-type header
String contentType = getContentType(name);//读取内容类型
if(contentType!= null){
response.setContentType(contentType);//重新设置内容类型
}
...try {
//将读取到的文件流以每次复制4096个字节的方式循环输出
copy(is, response.getOutputStream());
} finally {
is.close();
}
return;
}
}
}
}
如果用户请求的资源不是以/struts开头——可能是.jsp文件,也可能是.html文件,则通过过滤器链继续往下传送,直到到达请求的资源为止。
如果getMapping()方法返回有效的ActionMapping对象,则被认为正在请求某个Action,将调用 Dispatcher.serviceAction(request, response, servletContext, mapping)方法,该方法是处理Action的关键所在。
下面就来看serviceAction,这又回到全局变量dispatcher中了
//Load Action class for mapping and invoke the appropriate Action method, or go directly to the Result.public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,ActionMapping mapping)throws ServletException {
//createContextMap方法主要把Application、Session、Request的key value值拷贝到Map中
Map
// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
ValueStack
stack
=
(ValueStack)request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
boolean nullStack = stack == null;
if(nullStack){
ActionContext ctx = ActionContext.getContext();
if(ctx!= null){
stack = ctx.getValueStack();
}
}
if(stack!= null){
extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
}
String timerKey = ”Handling request from Dispatcher“;
try {
UtilTimerStack.push(timerKey);
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
Configuration config = configurationManager.getConfiguration();
//创建一个Action的代理对象,ActionProxyFactory是创建ActionProxy的工厂
//参考实现类:DefaultActionProxy和DefaultActionProxyFactory
ActionProxy
proxy
= config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
// if the ActionMapping says to go straight to a result, do it!
//如果是Result,则直接转向,关于Result,ActionProxy,ActionInvocation下一讲中再分析
if(mapping.getResult()!= null){
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
//执行Action
proxy.execute();
}
// If there was a previous value stack then set it back onto the request
if(!nullStack){
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
}
} catch(ConfigurationException e){
// WW-2874 Only log error if in devMode
if(devMode){
LOG.error(”Could not find action or result“, e);
}
else {
LOG.warn(”Could not find action or result“, e);
}
sendError(request, HttpServletResponse.SC_NOT_FOUND, e);
} catch(Exception e){
sendError(request,} finally {
UtilTimerStack.pop(timerKey);
}
} 下面开始讲一下主菜ActionProxy了.在这之前最好先去了解一下动态Proxy的基本知识.ActionProxy是Action的一个代理类,也就是说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法。归根到底,最后调用的是DefaultActionInvocation.invokeAction()方法。DefaultActionInvocation()->init()->createAction()。
最后
通
过
调
用ActionProxy.exute()-->ActionInvocation.invoke()-->Intercepter.intercept()-->ActionInvocation.invokeActionOnly()-->invokeAction()这里的步骤是先由ActionProxyFactory创建ActionInvocation和ActionProxy.public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map
ActionInvocation inv = new DefaultActionInvocation(extraContext, true);
container.inject(inv);
return }
public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map
createActionProxy(inv,namespace,actionName,methodName, executeResult, cleanupContext);
response,context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
response,context,ActionInvocation inv = new DefaultActionInvocation(extraContext, true);
container.inject(inv);
return }
下面先看DefaultActionInvocation的init方法
public void init(ActionProxy proxy){
this.proxy = proxy;
Map
// Setting this so that other classes, like object factories, can use the ActionProxy and other
// contextual information to operate
ActionContext actionContext = ActionContext.getContext();
if(actionContext!= null){
actionContext.setActionInvocation(this);
}
//创建Action,struts2中每一个Request都会创建一个新的Action
createAction(contextMap);
if(pushAction){
stack.push(action);
contextMap.put(”action“, action);
}
invocationContext = new ActionContext(contextMap);
invocationContext.setName(proxy.getActionName());
// get a new List so we don't get problems with the iterator if someone changes the list
List
interceptorList
=
new ArrayList
interceptors = interceptorList.iterator();
createActionProxy(inv,namespace,actionName,methodName, executeResult, cleanupContext);
}
protected void createAction(Map
// load action
String timerKey = ”actionCreate: “ + proxy.getActionName();
try {
UtilTimerStack.push(timerKey);
//默认为SpringObjectFactory:struts.objectFactory=spring.这里非常巧妙,在struts.properties中可以重写这个属性
//在前面BeanSelectionProvider中通过配置文件为ObjectFactory设置实现类
//这里以Spring为例,这里会调到SpringObjectFactory的buildBean方法,可以通过ApplicationContext的getBean()方法得到Spring的Bean
action
=
objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
} catch(InstantiationException e){
throw new
XWorkException(”Unable
to
intantiate
Action!“,e, proxy.getConfig());
} catch(IllegalAccessException e){
throw new XWorkException(”Illegal access to constructor, is it public?", e, proxy.getConfig());
} catch(Exception e){
...} finally {
UtilTimerStack.pop(timerKey);
}
if(actionEventListener!= null){
action = actionEventListener.prepare(action, stack);
}
}
//SpringObjectFactory
public Object buildBean(String beanName, Map
Object o = null;
try {
//SpringObjectFactory
会
通
过
web.xml
中的
第五篇:SAS复习资料
SAS复习资料 2013.6.20
说明:根据老师给的Html版整理,如有错误、遗漏敬请原谅,并及时指出,进行改正。谢谢!
1.研究因子:对试验指标有影响的,在试验中需要加以考察的条件。2.小机率原理:概率很小的事件,在一次试验中是不至于发生的。3.重复:每个参试的品种或处理占有两个或两个以上的小区称有重复。
4.局部控制:通过对小区的合理安排,把试验误差控制在一个局部的范围内。5.试验指标:试验中用来衡量试验效果的量。
6.复因子试验:包含两个或两个以上的因子的试验。7.集团(总体):根据研究目的确定的,凡符合指定条件的全部观察对象。8.偶然误差(机误):由于机会不等所造成的偏差。9.可量资料:能够以测量、称量的方法表示的资料。10.正交互作用(正连应):某些因子综合起来的效果大于这些因子单独作用的效果之和。1.进行随机区组的统计分析,需用何种方差分析?:双方面分类的方差分析 2.进行拉丁方的统计分析,需用何种方差分析?:三方面分类的方差分析 3.进行双方面分类的方差分析,总平方和分解为多少部份?:三部分 4.进行三方面分类的方差分析,总平方和分解为多少部份?:四部分
5.两因素(含交互作用)的方差分析,处理组合平方和应分解为多少部份?:四部分 6.三因素(含一级交互作用)的方差分析,处理组合平方和应分解为多少部份?:七部分 7.在几种常用的试验设计方法中,哪种精确度较高?:拉丁方 8.随机区组设计的误差自由度等于多少?:(m1)9.拉丁方设计的误差自由度等于多少?:(n2)10.只有重复而末实行局部控制的试验,应采用何种方差分析?:单方面分类的方差分析 1.样本标准差的功用?:反映样本的变异程度
2.样本平均数标准差(标准误)的功用?:反映在同一个总体进行抽样,所得的样本平均数间的差异,即抽样误差。
3.变异系数的功用?:用作两类事物的变异程度作比较
4.样本平均数的功用?:指示资料的中心位置,反映资料的一般质量水平,作为代表值同其它资料比较
5.协方差分析的功用?:用处理前的数据(基数)矫正处理后的数据,提高分析的精确度。6.样本均数差异显著性测验的功用?:在一定的概率保证下,判断事物间有否本质差异 7.总体均数区间估计的功用?:通过抽样,由样本的情况估计未知总体平均数的数值范围 8.在试验设计中,局部控制的作用?:减少试验误差
9.在试验设计中,重复的作用?:减少试验误差,估计试验误差,扩大试验的代表性 10.在试验设计中,随机排列的功用?:正确估计试验误差 1.何谓试验指标?:在试验中用来衡量试验效果的一个量
2.什么叫保护行?:防止试验材料受外来因素和周边环境影响作物行
3.某个复因子试验的处理组合数应如何计算?:等于有关因子的水平数乘积 4.在常用的试验设计中,哪种设计方法的精确度最高?:拉丁方 5.在常用的试验设计中,哪种设计方法的精确度最低?:间比法 6.试验设计三大原则是什么?:重复,局部控制,随机排列
7.作改良对比法设计时,参试的品种或处理数一般不大于多少?:不受限制 8.作随机区组设计时,参试的品种或处理数一般不大于多少?:不大于18 9.作配对法设计时,参试的品种或处理数一般不大于多少?:两个
10.作拉丁方设计时,参试的品种或处理数一般不大于多少?:不大于8 1.某个因子的自由度等于多少?:等于该因子的水平数减1 2.某两因子试验中,其交互作用的自由度等于多少?:等于有关因子的自由度的乘积
3.一可量资料样本均数与总体均数差异显箸性进行t检验时,其自由度为多少?:等于样本含量数-1 4.正交表的总自由度等于多少?:等于参试的处理组合数-1 5.作回归关系显著性测验时,回归项的自由度等于多少?:等于自变量的个数 6.作简单相关系数显著性测验时,DF等于多少?:等于N-2 7.2*2联卡平方测验时,DF等于多少?:1 8.两个配对法设计的可量资料样本均数差异显箸性进行t检验,其自由度为多少?:试验资料的配对数-1 9.2*J联卡平方测验时,其自由度为多少?:J-1 10.作拉丁方设计时,参试的品种或处理数一般不大于多少?:2 1.SS:平方和 2.N(0,1):标准正态分布 3.μ:总体平均数
4.CLM:平均数的置信区间 5.∑X :总和
6.VIF:方差膨胀因子 7.MSE:误差均方 8.DF :自由度 9.CV:变异系数 10.V:方差
1.欲进行聚类统计分析,需调用SAS系统的何种过程?:Proc cluster 2.欲进行回归统计分析,需调用SAS系统的何种过程?:Proc reg 3.欲进行方差统计分析,需调用SAS系统的何种过程?:Proc anova 4.欲进行因子统计分析,需调用SAS系统的何种过程?:Proc factor 5.欲进行典型相关统计分析,需调用SAS系统的何种过程?:Proc cancorr 6.欲进行基本统计量统计分析,需调用SAS系统的何种过程?:Proc means 7.欲进行主成分分析,需调用SAS系统的何种过程?:Proc princomp 8.欲进行成组法T测验,需调用SAS系统的何种过程?:Proc ttest 9.欲进行正态分布检验,需调用SAS系统的何种过程?:Procunivariate 10.欲进行作相关点式图,需调用SAS系统的何种过程?:Proc plot 1.单因子随机区组的方差分析模型(MODEL)是:Y=BLOCK T 2.单因子随机区组协方差分析的模型是(MODEL):Y=BLOCK T X 3.三元线性回归分析的模型是(MODEL):Y=X1 X2 X3 4.单方面分类的方差分析模型(MODEL)是:Y=T
5.两个因子变量的反应面分析的模型(MODEL)是:Y=X1 X2
6.单因子随机区组的多元方差分析的模型(MODEL)是:X1 X2 X3 =BLOCK T 7.3*4 复因子试验的方差分析模型(MODEL)是:Y=BLOCK A B A*B 8.拉丁方设计的方差分析模型(MODEL)是:Y=A B T 9.3*2*3复因子试验的方差分析模型(MODEL)是:Y=BLOCK A B C A*B A*C B*C A*B*C 10.正交随机区组(不考查交互作用)的统计分析模型(MODEL)是:Y=BLOCK A B C D 1.协方差分析的功用?:用处理前的数据(基数)矫正处理后的数据,提高分析的精确度 2.主成分分析的功用?:将个数众多、相互有关联的变量,转化为少数几个相互独立的变量 3.聚类分析的功用?:把样本或变量进行分类分
4.典型相关系数的功用?:反映两组不同性质的变量之间的关系密切程度 5.样本平均数的功用?:反映资料的一般质量水平,指示资料的中心位置 6.样本平均数标准差(标准误)的功用?:估计抽样误差
7.在回归分析中,残差的作用:反映实测值与预测值之间的偏差程度 8.在试验设计中,局部控制的作用?:减少试验误差 9.在试验设计中,重复的作用?:估计试验误差
10.变异系数的功用:用于两组资料的变异程度作比较
1.多重比较的方法有很多种,课本介绍了其中的三种: 第一种、最小显著差数法(Least Significant difference---LSD法或t测验法)第二种、Q测验法(最高显著差数法═Tukey测验法)
第三种、新复极差法(Shortest Significant Range---SSR法或Duncan法)哪种测验法的精确度较高?TUKEY法
2.不服从正态分布的数据不能直接作方差分析,必须进行数据转换,数据转换常用的方法有:(1)、平方根代换(2)、对数代换(3)、反正弦代换
问如果数据为二项分布的百分率,即可数百分数,且大于70%或小于30%,应采用何种代换?反正弦代换
3.计算步骤为:
第一步、将数据进行标准化; 第二步,求相关矩阵;
第三步,求相关矩阵的特征根、特征向量、各特征根的方差贡献率和累计方差贡献。第四步,根据特征根的累计方差贡献率保留前几个公共因子。
第五步,用前几个特征根的平方根乘相应的特征向量,构成因子载荷阵; 第六步,求相关系数矩阵的逆阵;
第七步,用因子载荷阵与相关矩阵的逆阵相乘,得回归系数阵; 第八步,用回归系数与标准化数据相乘得因子得分值。问这是何种统计分析方法?因子分析
4.计算步骤为:
第一步,将数据进行中心化; 第二步,求方差协方差矩阵; 第三步,求方差协方差矩阵的特征根、特征向量、各特征根的方差贡献率和累计方差贡献率。第四步,根据特征根的累计方差贡献率保留前几个主成分。
第五步,用中心化数据与前三个特征向量相乘,求得前三个主成分得分。
第六步,如果觉得有必要,用前三个特征根的平方根(即前几个主成分的标准差,)除前几个主成分得分值,得标准化主成分得分。第七步,如果有必要的话,利用这些标准化主成分得分作进一步的分析。问这是何种统计分析方法?主成分分析
5.计算步骤为:
第一步,计算X、Y、X*Y项的各种平方和(X为基数,Y为处理后的实测值;
第二步,进行X与Y项的回归关系显著性测验,若相关不显著,则进行一般的方差分析; 第三步,若相关显著,则扣除回归关系后,再进行方差分析; 第四步,用回归系数矫正处理后的数据测验,再进行多重比较。问这是何种统计分析方法?协方差分析
6.计算步骤为:
第一步,计算出k个类别的方差协方差矩阵的逆阵。
第二步,计算出各个训练样本到这k个类别的马氏距离,比较这k个距离,把训练样本归到距离最短的类中。
第三步,计算在第二步中判别错误的样本数占总样本数的百分率。第四步,如果还有新的待判样本,计算各个新样本到这k个类别的马氏距离,比较k个距离,把各个新样本归到距离最短的类中,再计算在待判样本中判别错误的样本数占待判样本总数的百分率。
问这是何种统计分析方法?判别分析
7.计算步骤为:
第一步,计算出Y的矫正数及各种平方和(Y为处理后的实测值)。第二步,列方差分析表并进行F测验。第三步,若F测验显著则进行多重比较。第四步,写出统计结论。
问这是何种统计分析方法?一元方差分析
8.计算步骤为:
第一步,按一定的原则选择k个凝聚点;
第二步,将所有事例点归到最靠近它的凝聚点所代表的类中,得到k个初始分类;
第三步,按最近距离的原则对初始分类进行修改;反复进行,直至分类合理为止。问这是何种统计分析方法?动态聚类
9.计算步骤为:
第一步,将原始数据进行中心化,按研究目的分为两组,记变量数(m1)较少的那组为X1,记变量数(m2)较多的那组为X2。
第二步,求X1和X2的方差协方差矩阵S11、S12和S22以及S12的转置阵S21,并利用它们构成非对称的方阵。
第三步,求非对称的方阵的特征根和对应的特征向量。
第四步,将这些特征向量除以非对称的方阵的特征根的平方根转换为第一组的典型系数。第五步,利用两个典型系数的关系式求出另一组的典型系数。第六步,将中心化数据和典型系数相乘得典型相关系数。问这是何种统计分析方法?典型相关分析 10.用SAS系统作数据分析,首要的问题是如何排列数据,你熟悉SAS系统对各种统计分析方法的数据排列的要求吗?问单因子试验采用随机区组设计,有四个试验指标时,数据应排多少列?。6列
:平方和
乘积和
合并样本百分数
样本标准差
样本平均数标准差
两样本百分数之差的总体标准差
两样本平均数之差的样本标准差
总体标准差
样本变异系数
样本差数平均数标准差
可量资料大样本均数与总体均数差异显箸性测验
可量资料两大样本均数差异显箸性测验 可数资料样本百分数与总体百分数差异显箸性测验
可数资料两大样本百分数差异显箸性测验
可量资料小样本均数与总体均数差异显箸性测验
可量资料两小样本均数差异显箸性测验(配对法)
可量资料两小样本均数差异显箸性测验(成组法)
由可量资料大样本对总体均数进行估计
由可量资料小样本对总体均数进行估计
由可数资料大样本百分数对总体百分数进行估计