`
文鸯
  • 浏览: 306118 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Struts源码学习 — 初始化ModuleConfig

阅读更多

Struts版本——1.2.9

Digester版本——1.6

 

 

初始化ModuleConfig就是指Struts将struts-config.xml初始化为ModuleConfig对象,实现这个动作的代码在ActionServlet的init()方法中,如下:

            initModuleConfigFactory();
            // Initialize modules as needed
            ModuleConfig moduleConfig = initModuleConfig("", config);
            initModuleMessageResources(moduleConfig);
            initModuleDataSources(moduleConfig);
            initModulePlugIns(moduleConfig);
            moduleConfig.freeze();
    
            Enumeration names = getServletConfig().getInitParameterNames();
            while (names.hasMoreElements()) {
                String name = (String) names.nextElement();
                if (!name.startsWith("config/")) {
                    continue;
                }
                String prefix = name.substring(6);
                moduleConfig = initModuleConfig
                    (prefix, getServletConfig().getInitParameter(name));
                initModuleMessageResources(moduleConfig);
                initModuleDataSources(moduleConfig);
                initModulePlugIns(moduleConfig);
                moduleConfig.freeze();
            }
    
            this.initModulePrefixes(this.getServletContext());
    
            this.destroyConfigDigester();

实际上,初始化ModuleConfig对象的过程仅仅在第3行的那句代码里,这里之所以列出这么多代码,是因为这段代码所做的事情可看成一个整体。对于这段代码的概括描述可参见Struts源码学习 — ActionServlet的初始化

 

 

将第3行代码里的initModuleConfig()方法挖开,如下:

    /**
     * <p>Initialize the module configuration information for the
     * specified module.</p>
     *
     * @param prefix Module prefix for this module
     * @param paths Comma-separated list of context-relative resource path(s)
     *  for this modules's configuration resource(s)
     *
     * @exception ServletException if initialization cannot be performed
     * @since Struts 1.1
     */
    protected ModuleConfig initModuleConfig(String prefix, String paths)
        throws ServletException {

        // :FIXME: Document UnavailableException? (Doesn't actually throw anything)

        if (log.isDebugEnabled()) {
            log.debug(
                "Initializing module path '"
                    + prefix
                    + "' configuration from '"
                    + paths
                    + "'");
        }

        // Parse the configuration for this module
        ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
        ModuleConfig config = factoryObject.createModuleConfig(prefix);

        // Configure the Digester instance we will use
        Digester digester = initConfigDigester();

        // Process each specified resource path
        while (paths.length() > 0) {
            digester.push(config);
            String path = null;
            int comma = paths.indexOf(',');
            if (comma >= 0) {
                path = paths.substring(0, comma).trim();
                paths = paths.substring(comma + 1);
            } else {
                path = paths.trim();
                paths = "";
            }

            if (path.length() < 1) {
                break;
            }

            this.parseModuleConfigFile(digester, path);
        }

        getServletContext().setAttribute(
            Globals.MODULE_KEY + config.getPrefix(),
            config);

        // Force creation and registration of DynaActionFormClass instances
        // for all dynamic form beans we wil be using
        FormBeanConfig fbs[] = config.findFormBeanConfigs();
        for (int i = 0; i < fbs.length; i++) {
            if (fbs[i].getDynamic()) {
                fbs[i].getDynaActionFormClass();
            }
        }

        return config;
    }

 

首先27、28两行,创建ModuleConfigFactory对象,其默认的实现是org.apache.struts.config.impl.DefaultModuleConfigFactory,可在web.xml中通过设置ActionServlet的configFactory初始化参数来改变实现类。然后由ModuleConfigFactory创建ModuleConfig对象,DefaultModuleConfigFactory的实现就是new一个org.apache.struts.config.impl.ModuleConfigImpl的对象,以prefix为构造方法的参数。

 

然后初始化Digester对象(后面详细说)。

 

因为参数paths可以是以逗号为分隔符的,多个struts-config.xml文件的路径,所以接下来的循环是用Digester对象分别对这多个struts-config.xml文件进行解析,解析的过程会将每个struts-config.xml文件里的元素都初始化为相应的XXXConfig对象,并将这些对象装进之前创建的ModuleConfig对象里。

 

然后将这个ModuleConfig对象放到ServletContext里。

 

59-64行,这一段是检查struts-config.xml文件里的所有form-bean元素,如果其type属性指定的类是动态FormBean,即org.apache.struts.action.DynaActionForm类或它的子类,就初始化FormBeanConfig的dynaActionFormClass字段。

 

最重要的代码在31行的initConfigDigester()方法里,挖开如下:

    /**
     * <p>Create (if needed) and return a new <code>Digester</code>
     * instance that has been initialized to process Struts module
     * configuration files and configure a corresponding <code>ModuleConfig</code>
     * object (which must be pushed on to the evaluation stack before parsing
     * begins).</p>
     *
     * @exception ServletException if a Digester cannot be configured
     * @since Struts 1.1
     */
    protected Digester initConfigDigester() throws ServletException {

        // :FIXME: Where can ServletException be thrown?

        // Do we have an existing instance?
        if (configDigester != null) {
            return (configDigester);
        }

        // Create a new Digester instance with standard capabilities
        configDigester = new Digester();
        configDigester.setNamespaceAware(true);
        configDigester.setValidating(this.isValidating());
        configDigester.setUseContextClassLoader(true);
        configDigester.addRuleSet(new ConfigRuleSet());

        for (int i = 0; i < registrations.length; i += 2) {
            URL url = this.getClass().getResource(registrations[i+1]);
            if (url != null) {
                configDigester.register(registrations[i], url.toString());
            }
        }

        this.addRuleSets();

        // Return the completely configured Digester instance
        return (configDigester);
    }

 

这个方法初始化Digester对象,就是这个Digester将struts-config.xml解析为ModuleConfig对象的。

 

Digester类的完全限定名为org.apache.commons.digester.Digester,来自于Apache Commons Digester,它是一个将XML映射到Java对象的工具。该工具底层还是使用SAX来解析XML,只是它在SAX的基础上,提出了一个Rule的概念。所谓Rule,通俗的解释就是“当扫描XML遇到某些结点时要做的事情”。Digester类根据这些Rule来解析XML,因此,解析之前需要给Digester添加这些Rule,Digester类里定义了一系列方法用来直接添加Rule。

 

也可以将添加Rule的繁琐工作委托给RuleSet来做,然后Digester调用addRuleSet(RuleSet)方法就行了。上面代码的25行就是这样做的,如何将struts-config.xml解析为ModuleConfig对象的Rule就是在ConfigRuleSet类的addRuleInstances()方法里添加到Digester的,该方法代码如下:

    /**
     * <p>Add the set of Rule instances defined in this RuleSet to the
     * specified <code>Digester</code> instance, associating them with
     * our namespace URI (if any).  This method should only be called
     * by a Digester instance.  These rules assume that an instance of
     * <code>org.apache.struts.config.ModuleConfig</code> is pushed
     * onto the evaluation stack before parsing begins.</p>
     *
     * @param digester Digester instance to which the new Rule instances
     *  should be added.
     */
    public void addRuleInstances(Digester digester) {

        digester.addObjectCreate
            ("struts-config/data-sources/data-source",
             "org.apache.struts.config.DataSourceConfig",
             "className");
        digester.addSetProperties
            ("struts-config/data-sources/data-source");
        digester.addSetNext
            ("struts-config/data-sources/data-source",
             "addDataSourceConfig",
             "org.apache.struts.config.DataSourceConfig");

        digester.addRule
            ("struts-config/data-sources/data-source/set-property",
             new AddDataSourcePropertyRule());

        digester.addRule
            ("struts-config/action-mappings",
             new SetActionMappingClassRule());

        digester.addFactoryCreate
            ("struts-config/action-mappings/action",
             new ActionMappingFactory());
        digester.addSetProperties
            ("struts-config/action-mappings/action");
        digester.addSetNext
            ("struts-config/action-mappings/action",
             "addActionConfig",
             "org.apache.struts.config.ActionConfig");

        digester.addSetProperty
            ("struts-config/action-mappings/action/set-property",
             "property", "value");

        digester.addObjectCreate
            ("struts-config/action-mappings/action/exception",
             "org.apache.struts.config.ExceptionConfig",
             "className");
        digester.addSetProperties
            ("struts-config/action-mappings/action/exception");
        digester.addSetNext
            ("struts-config/action-mappings/action/exception",
             "addExceptionConfig",
             "org.apache.struts.config.ExceptionConfig");

        digester.addSetProperty
            ("struts-config/action-mappings/action/exception/set-property",
             "property", "value");

        digester.addFactoryCreate
            ("struts-config/action-mappings/action/forward",
             new ActionForwardFactory());
        digester.addSetProperties
            ("struts-config/action-mappings/action/forward");
        digester.addSetNext
            ("struts-config/action-mappings/action/forward",
             "addForwardConfig",
             "org.apache.struts.config.ForwardConfig");

        digester.addSetProperty
            ("struts-config/action-mappings/action/forward/set-property",
             "property", "value");

        digester.addObjectCreate
            ("struts-config/controller",
             "org.apache.struts.config.ControllerConfig",
             "className");
        digester.addSetProperties
            ("struts-config/controller");
        digester.addSetNext
            ("struts-config/controller",
             "setControllerConfig",
             "org.apache.struts.config.ControllerConfig");

        digester.addSetProperty
            ("struts-config/controller/set-property",
             "property", "value");

        digester.addRule
            ("struts-config/form-beans",
             new SetActionFormBeanClassRule());

        digester.addFactoryCreate
            ("struts-config/form-beans/form-bean",
             new ActionFormBeanFactory());
        digester.addSetProperties
            ("struts-config/form-beans/form-bean");
        digester.addSetNext
            ("struts-config/form-beans/form-bean",
             "addFormBeanConfig",
             "org.apache.struts.config.FormBeanConfig");

        digester.addObjectCreate
            ("struts-config/form-beans/form-bean/form-property",
             "org.apache.struts.config.FormPropertyConfig",
             "className");
        digester.addSetProperties
            ("struts-config/form-beans/form-bean/form-property");
        digester.addSetNext
            ("struts-config/form-beans/form-bean/form-property",
             "addFormPropertyConfig",
             "org.apache.struts.config.FormPropertyConfig");

        digester.addSetProperty
            ("struts-config/form-beans/form-bean/form-property/set-property",
             "property", "value");

        digester.addSetProperty
            ("struts-config/form-beans/form-bean/set-property",
             "property", "value");

        digester.addObjectCreate
            ("struts-config/global-exceptions/exception",
             "org.apache.struts.config.ExceptionConfig",
             "className");
        digester.addSetProperties
            ("struts-config/global-exceptions/exception");
        digester.addSetNext
            ("struts-config/global-exceptions/exception",
             "addExceptionConfig",
             "org.apache.struts.config.ExceptionConfig");

        digester.addSetProperty
            ("struts-config/global-exceptions/exception/set-property",
             "property", "value");

        digester.addRule
            ("struts-config/global-forwards",
             new SetActionForwardClassRule());

        digester.addFactoryCreate
            ("struts-config/global-forwards/forward",
             new GlobalForwardFactory());
        digester.addSetProperties
            ("struts-config/global-forwards/forward");
        digester.addSetNext
            ("struts-config/global-forwards/forward",
             "addForwardConfig",
             "org.apache.struts.config.ForwardConfig");

        digester.addSetProperty
            ("struts-config/global-forwards/forward/set-property",
             "property", "value");

        digester.addObjectCreate
            ("struts-config/message-resources",
             "org.apache.struts.config.MessageResourcesConfig",
             "className");
        digester.addSetProperties
            ("struts-config/message-resources");
        digester.addSetNext
            ("struts-config/message-resources",
             "addMessageResourcesConfig",
             "org.apache.struts.config.MessageResourcesConfig");

        digester.addSetProperty
            ("struts-config/message-resources/set-property",
             "property", "value");

        digester.addObjectCreate
            ("struts-config/plug-in",
             "org.apache.struts.config.PlugInConfig");
        digester.addSetProperties
            ("struts-config/plug-in");
        digester.addSetNext
            ("struts-config/plug-in",
             "addPlugInConfig",
             "org.apache.struts.config.PlugInConfig");

        digester.addRule
            ("struts-config/plug-in/set-property",
             new PlugInSetPropertyRule());

    }

 

这里的所有addXXX()方法都是在添加Rule,只不过其中不叫addRule的方法是添加Digester的内置Rule的便捷方法。所有方法的第一个参数都是一个XPath格式的String,这些String看着都很眼熟吧,没错,都是struts-config.xml里的。

 

先说说Digester是如何使用Rule来解析XML的,执行Digester类的parse()方法来扫描解析XML,当扫描XML遇到匹配某个XPath的标签,就开始使用Digester里对应于这个XPath的Rule。碰到开始标签时,调用Rule的begin()方法;标签如果有体,调用Rule的body()方法;碰到结束标签时,调用Rule的end()方法。如果对应于某个XPath有多个Rule,就有个调用顺序的问题了。对于begin()方法,是按照Rule添加到Digester里的顺序调用;end()方法调用顺序与begin()相反。这点跟栈的思想一样。

 

这段代码里使用到的一些Digester内置Rule有:

ObjectCreateRule:创建对象并压栈。

FactoryCreateRule:由工厂来创建对象并压栈。

SetPropertiesRule:将标签属性值设置到栈顶对象的属性里。

SetPropertyRule:设置栈顶对象的单个属性的值。

SetNextRule:调用栈顶第2个元素的指定方法来建立它和栈顶元素的关系。

 

一般对标签的处理方式是,先用ObjectCreateRule或FactoryCreateRule创建对象,然后用SetPropertiesRule或SetPropertyRule设置对象的属性值,最后用SetNextRule建立该标签和父标签的关系。上面的代码基本就是这个套路,另外还加入了一些Struts自定义的Rule,如下:

AddDataSourcePropertyRule:设置DataSource的属性。

PlugInSetPropertyRule:设置PlugIn的属性。

SetActionMappingClassRule:根据struts-config/action-mappings标签的type属性,设置ActionConfig的实现类。

SetActionFormBeanClassRule:根据struts-config/form-beans标签的type属性,设置FormBeanConfig的实现类。

SetActionForwardClassRule:根据struts-config/global-forwards标签的type属性,设置ForwardConfig的实现类。

 

对于ActionConfig、FormBeanConfig、ForwardConfig,有3种方式可以改变这3个XXXConfig的实现类。

1. 使用自定义的ModuleConfig实现类,在其中定义XXXConfig的实现类,这个改变影响范围最大,针对于整个应用的XXXConfig。Struts默认的ModuleConfig实现类是org.apache.struts.config.impl.ModuleConfigImpl,这个类里面定义了XXXConfig的默认实现类,分别是org.apache.struts.action.ActionMapping、org.apache.struts.action.ActionFormBean、org.apache.struts.action.ActionForward。

2. 象上面最后的3个Rule说明中提到的那样,设置type属性,这个改变只针对于单个struts-config.xml中的XXXConfig。

3. 具体到单个struts-config.xml中的单个XXXConfig配置,设置它的className属性,来改变单个XXXConfig的实现类,这个改变影响最小,只针对单个XXXConfig。

正因为它们的实现类可以这样灵活的改变,所以上面代码在为Digester添加创建它们实例的Rule时,使用的是FactoryCreateRule,而不是ObjectCreateRule。要构造一个FactoryCreateRule,需要为它提供一个ObjectCreationFactory,前者将创建对象的工作委托给后者。Struts提供了创建这3种Config对象的ObjectCreationFactory——ActionMappingFactory、ActionFormBeanFactory、ActionForwardFactory、GlobalForwardFactory。如果标签给出了className属性,这些Factory就以该属性值创建对象;如果没有,就以之前设置的实现类创建对象。

分享到:
评论
1 楼 xhsbetter 2009-01-13  
学习了

相关推荐

    多目标白鲸优化算法MOBWO:在多目标测试函数中的实证与应用分析,多目标白鲸优化算法MOBWO的实证研究:在九个测试函数中的表现与评估,多目标白鲸优化算法MOBWO 在9个多目标测试函数中测试 Mat

    多目标白鲸优化算法MOBWO:在多目标测试函数中的实证与应用分析,多目标白鲸优化算法MOBWO的实证研究:在九个测试函数中的表现与评估,多目标白鲸优化算法MOBWO 在9个多目标测试函数中测试 Matlab语言 程序已调试好,可直接运行,算法新颖 1将蛇优化算法的优良策略与多目标优化算法框架(网格法)结合形成多目标蛇优化算法(MOSO),为了验证所提的MOSO的有效性,将其在9个多目标测试函数 (ZDT1、ZDT2、ZDT3、ZDT4、ZDT6、Kursawe、Poloni,Viennet2、Viennet3) 上实验,并采用IGD、GD、HV、SP四种评价指标进行评价,部分效果如图1所示,可完全满足您的需求~ 2源文件夹包含MOBWO所有代码(含9个多目标测试函数)以及原始白鲸优化算法文献 3代码适合新手小白学习,一键运行main文件即可轻松出图 4仅包含Matlab代码,后可保证原始程序运行~ ,多目标白鲸优化算法(MOBWO); 测试函数; Matlab语言; 程序调试; 算法新颖; 多目标蛇优化算法(MOSO); IGD、GD、HV、SP评价指标; 代码学习; 轻松出图。,基于

    【图像加密】基于matlab图像加密的混沌地图晶格系统的评估【含Matlab源码 9901期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【图像融合】基于matlab像素的多焦点和多光谱图像融合【含Matlab源码 7572期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    中国石油微服务开发REST API接口定义规范及其安全设计

    内容概要:本文介绍了在中国石油勘探开发梦想云平台上定义REST API接口的基本规范,旨在提高接口质量,便于开发、测试和维护。主要内容包括REST API的基础概念,设计流程,URI、HTTP方法及响应状态码的运用,API文档的管理以及Swagger工具的应用,还详细阐述了API安全认证,特别是JWT的应用。通过这份文档能够帮助开发者理解和实施高质量的微服务架构。 适用人群:适用于参与或计划参与微服务项目的开发团队,尤其是那些致力于提升REST API接口质量和效率的专业技术人员。 使用场景及目标:文档的目标在于引导用户理解REST API接口设计的关键要素,如资源命名、方法选择等,并教会他们如何有效管理和保护这些API,确保其稳定性和安全性。通过实践本指南的原则,用户可以构建出更加健壮的分布式应用程序接口。 其他说明:此外,文中提供了大量关于API文档生成与维护的最佳做法,强调了文档更新须与代码同步,同时也探讨了API变更管理的有效方法。在安全方面,重点讲述了JWT的构成及其工作机制,展示了利用JWT实现高效认证的具体实例。

    【电力变压器】基于matlab电力变压器能量限制【含Matlab源码 10013期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    Matlab实现基于BiLSTM-Adaboost双向长短期记忆神经网络结合Adaboost集成学习多输入单输出时间序列预测的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:该文档详细介绍了基于双向长短期记忆(BiLSTM)神经网络与Adaboost集成学习的时间序列预测模型及其应用。文中阐述了项目背景,指出了传统LSTM在复杂数据下存在的局限,提出了通过BiLSTM增强前后依赖关系,并结合Adaboost优化模型精度与泛化能力的方法。全文涵盖了从数据预处理、特征提取到建模、评估、以及GUI设计在内的全过程,并展示了该模型在金融预测、气象预报、能源管理和生产调度等多个领域的广泛应用潜力。文章还包括对代码片段的具体解析、模型部署的考量及未来发展的展望。 适合人群:拥有基本的机器学习与神经网络基础的研究人员和技术开发者,尤其是那些正在寻找时间序列数据分析解决方案的专业人士。 使用场景及目标:1. 多个领域如金融市场、气象预测等的时间序列数据处理任务中;2. 解决传统单一神经网络可能出现的过拟合并优化模型的鲁棒性和准确性。 其他说明:除了详细讲解如何使用Matlab实施完整的BiLSTM和Adaboost集成外,文中还特别注意到了模型调优的重要性——通过超参数搜索、早停策略和其他正则化技巧以预防过拟合情况的发生。此外,文档还讨论了有关实时数据处理、模型安全性和可移植性的要点。附带完整的Matlab代码实现了从环境准备直到预测结果可视化的每一个步骤,使读者可以很容易地复现和定制整个工作流程。

    【重力仿真】基于matlab GUI水平圆柱体重力异常正演【含Matlab源码 11176期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    Go语言1.24版本新特性详解与高性能博客系统miniblog实战项目

    内容概要:Go 1.24 版本引入了多项关键改进,其中包括:泛型类型别名,允许类型别名携带类型参数,简化代码实现;弱指针避免对象因包含在缓存中而无法被释放的问题;改进了终结器,提供了新的运行时函数 AddCleanup 以增强对象清理的灵活性和可靠性。另外,Go 1.24 改善了 map 的默认实现,显著提升了其运行时性能。与此同时,开源项目 miniblog 是一个功能全面、易于理解的 Go 实战项目。该项目采用了类似 Kubernetes 的三层架构设计,涵盖了许多 Go 项目开发的最佳实践和技术栈,不仅有助于开发者理解 Go 项目的核心理念和实施方法,还能提供一系列开发脚手架工具、配套课程和支持材料,以便更轻松地开展实际项目。 适合人群:1年以上 Go 开发经验的研发人员或正在寻找优秀 Go 项目充实自己简历的技术人员。 使用场景及目标:该总结的目标是帮助有一定 Go 基础的知识分子迅速了解新特性及其实用价值。miniblog 项目特别适用于希望加深对 Go 实践认识的学习者,尤其是那些想要通过参与实际编码练习和深入理解 Go 内部工作机制的人群。通过这两个方面的内容学习可以帮助使用者更好地理解 Go 新增特性的应用前景和发展方向,并能够在实践中灵活应用。 其他说明:本文档不仅涵盖了新特性的技术和理论要点,同时也展示了如何通过动手实践强化技能的具体例子。阅读本文不仅可以学到最新的 Go 编程技巧,还将了解到实际开发过程中面临的挑战及其解决方案。此外,还提供了一份详细的安装指导,以及一些常见的操作指南。对于新手而言,可以通过提供的完整配套资料逐步建立起个人的知识体系;而对于资深开发者,则可以在更高层次上审视自身项目的架构设计,进而推动技术创新和个人职业发展。

    智能对话机器人+deepseek+支持微信公众号、企业微信应用、飞书、钉钉接入+基于大模型的智能对话机器人,支持微信公众号、企业

    CoW项目是基于大模型的智能对话机器人,支持微信公众号、企业微信应用、飞书、钉钉接入,可选择GPT3.5/GPT4.0/Claude/Gemini/LinkAI/ChatGLM/KIMI/文心一言/讯飞星火/通义千问/LinkAI,能处理文本、语音和图片,通过插件访问操作系统和互联网等外部资源,支持基于自有知识库定制企业AI应用。 功能如下: 1、 多端部署: 有多种部署方式可选择且功能完备,目前已支持微信公众号、企业微信应用、飞书、钉钉等部署方式 2、 基础对话: 私聊及群聊的消息智能回复,支持多轮会话上下文记忆,支持 GPT-3.5, GPT-4o-mini, GPT-4o, GPT-4, Claude-3.5, Gemini, 文心一言, 讯飞星火, 通义千问,ChatGLM-4,Kimi(月之暗面), MiniMax, GiteeAI 3、 语音能力: 可识别语音消息,通过文字或语音回复,支持 azure, baidu, google, openai(whisper/tts) 等多种语音模型 4、 图像能力: 支持图片生等

    【车间调度】基于matlab哈里斯鹰算法HHO求解分布式置换流水车间调度DPFSP【含Matlab源码 6143期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【图像处理】颜色恒常性算法水下图像处理【含Matlab源码 474期】.md

    CSDN Matlab武动乾坤上传的资料均是完整代码运行出的仿真结果图,可见完整代码亲测可用,适合小白; 1、完整的代码内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【图像去噪】基于matlab中值滤波、均值滤波和非局部均值滤波NLM图像去噪【含Matlab源码 10364期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    基于LabVIEW的滚动轴承故障诊断系统:一种振动信号采集与故障诊断的实用设计与实践验证,基于LabVIEW的滚动轴承高效故障诊断系统设计与应用研究,基于LabVIEW的滚动轴承故障诊断系统. 实现对

    基于LabVIEW的滚动轴承故障诊断系统:一种振动信号采集与故障诊断的实用设计与实践验证,基于LabVIEW的滚动轴承高效故障诊断系统设计与应用研究,基于LabVIEW的滚动轴承故障诊断系统. 实现对滚动轴承工作状态的监测,提出了一种基于 Lab VIEW 的滚动轴承故障诊断系统的设计方案,给出了滚动轴承振动信号的采集与故障诊断方法,在 Lab VIEW 的诊断平台下进行信号处理与分析,然后结合滚动轴承故障诊断理论与信号分析结果来对该轴承运行状态进行判断。 最后利用旋转机械振动及故障模拟试验平台对该系统进行验证,验证结果体现了该系统具有可行性和适用性。 ,LabVIEW; 滚动轴承故障诊断系统; 振动信号采集; 故障诊断方法; 信号处理与分析; 验证测试; 可行性; 适用性,基于LabVIEW的滚动轴承故障诊断系统设计与验证

    Javascript语言视频教程.zip

    Javascript语言视频教程,涵盖Javascript语言基础和高级教程,零基础入门。

    在链表的前面-开头插入一个节点

    python在链表的前面-开头插入一个节点

    【图像融合】加权平均+HIS+高通滤波+灰度调制图像融合【含Matlab源码 8041期】.md

    CSDN Matlab武动乾坤上传的资料均是完整代码运行出的仿真结果图,可见完整代码亲测可用,适合小白; 1、完整的代码内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    《基于改进动态窗口DWA模糊自适应调整权重的路径规划算法研究及其MATLAB实现》,《基于改进动态窗口DWA的模糊自适应权重调整路径规划算法及其MATLAB实现》,基于改进动态窗口 DWA 模糊自适应

    《基于改进动态窗口DWA模糊自适应调整权重的路径规划算法研究及其MATLAB实现》,《基于改进动态窗口DWA的模糊自适应权重调整路径规划算法及其MATLAB实现》,基于改进动态窗口 DWA 模糊自适应调整权重的路径基于改进动态窗口 DWA 模糊自适应调整权重的路径规划算法 MATLAB 源码+文档 《栅格地图可修改》 基本DWA算法能够有效地避免碰撞并尽可能接近目标点,但评价函数的权重因子需要根据实际情况进行调整。 为了提高DWA算法的性能,本文提出了一种改进DWA算法,通过模糊控制自适应调整评价因子权重,改进DWA算法的实现过程如下: 定义模糊评价函数。 模糊评价函数是一种能够处理不确定性和模糊性的评价函数。 它将输入值映射到模糊隶属度,根据规则计算输出值。 在改进DWA算法中,我们定义了一个三输入一输出的模糊评价函数,输入包括距离、航向和速度,输出为权重因子。 [1]实时调整权重因子。 在基本DWA算法中,权重因子需要根据实际情况进行调整,这需要人工干预。 在改进DWA算法中,我们通过模糊控制实现自适应调整,以提高算法的性能。 [2]评估路径。 通过路径的长度和避障情况等指标评估路

    基于MATLAB平台PCA算法的人脸识别系统:程序调试成功,可替换数据获取高准确率识别结果,基于MATLAB平台PCA算法的人脸识别系统:程序调试与自我数据替换实现高精度识别结果,基于MATLAB平台

    基于MATLAB平台PCA算法的人脸识别系统:程序调试成功,可替换数据获取高准确率识别结果,基于MATLAB平台PCA算法的人脸识别系统:程序调试与自我数据替换实现高精度识别结果,基于MATLAB平台PCA的人脸识别,程序已调通,可将自己的数据替进行识别。 得到识别准确率结果。 ,基于MATLAB平台PCA的人脸识别; 程序已调通; 数据替换; 识别准确率。,MATLAB平台PCA人脸识别程序:调通后实现高准确率识别

    【潮流计算】基于matlab GUI牛顿拉夫逊法解潮流【含Matlab源码 11034期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

Global site tag (gtag.js) - Google Analytics