Struts2源码阅读(四)_DispatcherConfigurationProvider续

接下来第三步: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 = (Settings) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className), null);     } catch (Exception e) {     LOG.error("Settings: Could not instantiate the struts.configuration object, substituting the default implementation.", e);     }     }     } 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 prov = (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; }     public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {     props.putAll(initParams);//在这里实现滴~     }     });     }  
第七步:init_AliasStandardObjects,使用BeanSelectionProvider
这是将配置文件中定义的<bean>与实际的类相映射,就是注入bean的依赖关系,这部分以后有时候再研究Container
 
接下来是看怎样调用这些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;     } 
展开DefaultConfiguration中的reloadContainer

public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {     packageContexts.clear();     loadedFileNames.clear();     List<PackageProvider> packageProviders = new ArrayList<PackageProvider>();     //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<Configuration>() {     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<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);     if (packageProviderNames != null) {     for (String name : packageProviderNames) {     PackageProvider provider = container.getInstance(PackageProvider.class, name);     provider.init(this);     provider.loadPackages();     packageProviders.add(provider);     }     }     rebuildRuntimeConfiguration();     } finally {     if (oldContext == null) {     ActionContext.setContext(null);     }     }     return packageProviders;     }     

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497919.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI 与区块链:两大热门技术,会碰撞出什么样的火花?

来源&#xff1a;36氪概要&#xff1a;区块链和AI可以说是当今最热门的两个技术方向了。区块链和AI可以说是当今最热门的两个技术方向了。在一般人看来&#xff0c;这两大技术似乎没有什么交叉的地方&#xff0c;因为区块链和AI分别属于是技术谱系的两个极端&#xff1a;一个是…

php5.5升级到php5.6,从php5.5.9升级到php5.6之后,相当于php5enmod?

在ubuntu服务器中,我曾经为php5.5.9安装模块,例如带有apt-get的mcrypt,然后使用sudo php5enmod mcrypt启用了它.现在,我已经升级到php5.6,并且错过了一个在Laravel 4.2中与PHPThumb一起使用的模块,该模块需要GID或Imagick来修改图像.所以我做了 &#xff1a;$sudo apt-get inst…

伯克利人工智能研究院最新研究:协作型工业机器人如何更智能?

原文来源&#xff1a;BAIR作者&#xff1a;Changliu Liu、Masayoshi Tomizuka「雷克世界」编译&#xff1a;嗯~阿童木呀、我是卡布达在现代工厂中&#xff0c;工人和机器人是两大主要劳动力。出于安全考虑&#xff0c;这两者通常被限制在金属笼中的机器人分离开来&#xff0c;而…

Struts2源码阅读(五)_FilterDispatcher核心控制器

Dispatcher已经在之前讲过&#xff0c;这就好办了。FilterDispatcher是Struts2的核心控制器&#xff0c;首先看一下init()方法。 public void init(FilterConfig filterConfig) throws ServletException { try { this.filterConfig filterConfig; initLogging(); …

Php如何过360拦截,PHP常见漏洞修复文件-360漏洞修复插件

主要对常见的漏洞进行拦截&#xff0c;如&#xff1a;SQL注入漏洞、检测POST数据、XSS漏洞防护等&#xff0c;效果非常不错&#xff0c;值得拥有。1、下载:360漏洞修复插件2、解压后&#xff0c;上传整个文件夹至服务器根目录3、if(is_file($_SERVER[DOCUMENT_ROOT]./360safe/3…

谷歌开源 TFGAN,让训练和评估 GAN 变得更加简单

作者&#xff1a;思颖概要&#xff1a;训练神经网络的时候&#xff0c;通常需要定义一个损失函数来告诉网络它离目标还有多远。三年前&#xff0c;蒙特利尔大学 Ian Goodfellow 等学者提出「生成式对抗网络」&#xff08;Generative Adversarial Networks&#xff0c;GANs&…

Struts2源码阅读(六)_ActionProxyActionInvocation

下面开始讲一下主菜ActionProxy了.在这之前最好先去了解一下动态Proxy的基本知识.ActionProxy是Action的一个代理类&#xff0c;也就是说Action的调用是通过ActionProxy实现的&#xff0c;其实就是调用了ActionProxy.execute()方法&#xff0c;而该方法又调用了ActionInvocatio…

py语言和php,php和python什么区别

python语言的风格Python在设计上坚持了清晰划一的风格&#xff0c;这使得Python成为一门易读、易维护&#xff0c;并且被大量用户所欢迎的、用途广泛的语言。设计者开发时总的指导思想是&#xff0c;对于一个特定的问题&#xff0c;只要有一种最好的方法来解决就好了。这在由Ti…

计算机产业深度报告:云计算与人工智能开启新一轮技术变革周期

来源&#xff1a;乐晴智库概要&#xff1a;每一次的技术迭代都将行业推向新的高度&#xff0c;同时也对产业生态和企业兴衰产生重大影响。纵观整个IT产业的发展史&#xff0c;从1960年代到现在的2010年代&#xff0c;科技行业历经了大型机时代、小型机时代、PC时代、互联网时代…

自动分页,返回时跳回指定页

实现原理&#xff1a; displaytag 自动分页时&#xff0c;只需要提供一个“集合”(name 属性) 和翻页对应的 requestURI 属性&#xff08;也是返回整体的集合&#xff09; 执行翻页时 displaytag 会自动计算出页数&#xff0c;形如&#xff1a; http://localhost:8080/bpp/ma…

java 界面艺术字,Java 在Word文档中添加艺术字

与普通文字相比&#xff0c;艺术字更加美观有趣也更具有辨识度&#xff0c;常见于一些设计精美的杂志或宣传海报中。我们在日常工作中编辑Word文档时&#xff0c;也可以通过添加艺术字体来凸显文章的重点,美化页面排版。这篇文章将介绍如何使用FreeSpire.Doc for Java在word文档…

AI校招程序员最高薪酬曝光!腾讯80万年薪领跑,还送北京户口

来源&#xff1a;100offer概要&#xff1a;如果说 2016 年是互联网 AI 领域井喷的元年&#xff0c;2017 年整个 AI 领域全面爆发&#xff0c;来潮汹涌的趋势相较 2016 年可以说是有过之而无不及。如果说 2016 年是互联网 AI 领域井喷的元年&#xff0c;2017 年整个 AI 领域全面…

集合对象-“块数据”操作--其实是同一对象引用

例如&#xff1a; Set set1 new HashSet(); set1.add( object1 ); set1.add( ... ); set1.add( objectn ); Set set2 new HashSet( set1 ); 或者 Set set3 new HashSet( set1 ); set3.addAll( set1 ); set2 与 set3 中存储的都是 set1 元素的 “引用” 代码如…

vscode php断点,VSCode中设置断点调试PHP(示例代码)

所需文件xampp 集成服务器(本文使用Apache2.4MySQLPHP7.4.3)vscodeXdebugphp-debug 插件配置Xdebug1. 下载Xdebug插件 (直接去 https://xdebug.org/download.php下载php对应版本的插件)如果不知道如何选取版本&#xff0c;则如下Step 1&#xff1a;获取本地php版本信息 (利用ph…

2017英国AI形势报告:认知鸿沟、新商业模式和当下的挑战

原作 David Kelnar MMC投资研究中心老大Root 编译自 MMC Venture量子位 出品 | 公众号 QbitAI来源&#xff1a;36氪概要&#xff1a;AI技术今年所获得媒体、资本极度的关注&#xff0c;短时间内已经给民众带来认知上剧烈的冲击&#xff1a;或是由未知产生恐惧&#xff0c;或是对…

仓储物流参考资料

一种集成化仓储管理系统研究 http://www.docin.com/p-47000094.html 基于单据流程管理的仓储管理系统的研究 http://articles.e-works.net.cn/BPM/Article65651.htm

accept标头 php,如何在PHP中读取任何请求标头

如何在PHP中读取任何请求标头我应该如何阅读PHP中的任何标题&#xff1f;例如&#xff0c;自定义标头&#xff1a;X-Requested-With。Sabya asked 2019-02-28T12:09:45Z14个解决方案349 votes$_SERVER[HTTP_X_REQUESTED_WITH]RFC3875,4.1.18&#xff1a;如果使用的协议是HTTP&a…

前百度首席科学家吴恩达携手富士康,要用人工智能升级制造业

来源&#xff1a;澎湃新闻概要&#xff1a;当地时间12月14日&#xff0c;吴恩达再一次通过英文自媒体平台Medium公布了自己的下一个创业项目——Landing.ai。作为人工智能领域里的明星科学家、斯坦福大学计算机系教授吴恩达&#xff08;Andrew Ng&#xff09;&#xff0c;离开百…

特殊SQL示例

ProductsData pd_num pd_type pd_statusSCS-1-00 SCS-1 0 SCS-1-002 SCS-1 0 SCS-2-001 SCS-2 0 SCS-2-001 SCS-2 1结果(num1 是pd_status0的个数&#xff0c;num1 是pd_status1的个数&#xff09;pd_type num1 num2scs-1 2…

php静态文件怎么生成器,[新姿势]我用过的静态站点生成器们

随着诸如github pages的静态托管服务&#xff0c;静态站点生成器在近年有了极大的发展&#xff0c;静态生成托管对托管环境要求低、维护简单、可配合版本控制&#xff0c;但又灵活多变&#xff0c;在程序员和geek群体中大有超越WordPress等动态博客程序的势头近年来个人也好项目…