网站建设推广语/西青seo

网站建设推广语,西青seo,做彩票网站模板,桂林象鼻山属于哪个区文章目录 一、前言二、源码解析GenericXMLConfiguratorlogback.xml解析通过SaxEvent构建节点model解析model节点DefaultProcessor解析model 三、总结 一、前言 上一篇介绍了logback模块解析logback.mxl文件的入口, 我们可以手动指定logback.xml文件的位置, 也可以使用其它的名…

文章目录

  • 一、前言
  • 二、源码解析
    • GenericXMLConfigurator
      • logback.xml解析
      • 通过SaxEvent构建节点model
      • 解析model节点
      • DefaultProcessor解析model
  • 三、总结

一、前言

上一篇介绍了logback模块解析logback.mxl文件的入口, 我们可以手动指定logback.xml文件的位置, 也可以使用其它的名字, 本节我们继续讨论logback是如何解析logback.xml文件的。

二、源码解析

拿出我们上一节的继承图
在这里插入图片描述

其中ContextAwareContextAwareBase是有关日志上下文LoggerContext注入与打印启动日志的, 我们不介绍。

看到这个Aware结尾的有的同学可能会感觉到很有亲切感, 没错, spring中有很多这种Aware结尾的类, 例如ApplicationContextAwareEnvironmentAware等xxxAware, 它们都会提供一个setXxx的方法, 用来在框架启动的时候注入一个xxx对象。

GenericXMLConfigurator

public abstract class GenericXMLConfigurator extends ContextAwareBase {/*** SaxEvent解析器*/protected SaxEventInterpreter saxEventInterpreter;/*** model解析器的上下文*/protected ModelInterpretationContext modelInterpretationContext;/*** 配置文件节点路径和action的映射* 默认是SimpleRuleStore*/private RuleStore ruleStore;public final void doConfigure(URL url) throws JoranException {InputStream in = null;try {// 1.给Context设置ConfigurationWatchList; 用于配置文件热更新informContextOfURLUsedForConfiguration(getContext(), url);URLConnection urlConnection = url.openConnection();// per http://jira.qos.ch/browse/LOGBACK-117  LBCORE-105// per http://jira.qos.ch/browse/LOGBACK-163  LBCORE-127urlConnection.setUseCaches(false);in = urlConnection.getInputStream();// 2.解析配置; url.toExternalForm():返回url表示的绝对路径的字符串形式doConfigure(in, url.toExternalForm());} catch (IOException ioe) {String errMsg = "Could not open URL [" + url + "].";// 打印解析异常日志addError(errMsg, ioe);throw new JoranException(errMsg, ioe);} finally {if (in != null) {try {// 3.关闭流in.close();} catch (IOException ioe) {String errMsg = "Could not close input stream";addError(errMsg, ioe);throw new JoranException(errMsg, ioe);}}}}
}

这个方法就是开始解析logback.xml文件真正的入口了public final void doConfigure(URL url) throws JoranException

  1. informContextOfURLUsedForConfiguration方法用来设置动态热加载的配置文件, 也就是我们<configuration debug="true" scan="true" scanPeriod="10 second"> 这里动态刷新的默认文件
  2. doConfigure: 进一步解析

doConfigure(final InputSource inputSource)

直接从doConfigure跳过来看这个方法即可

public final void doConfigure(final InputSource inputSource) throws JoranException {// 发布配置开始事件context.fireConfigurationEvent(newConfigurationStartedEvent(this));long threshold = System.currentTimeMillis();// 1.解析日志配置文件; 例如logback.xmlSaxEventRecorder recorder = populateSaxEventRecorder(inputSource);// 获取解析节点的结果; 每个节点都会解析成StartEvent, BodyEvent, EndEventList<SaxEvent> saxEvents = recorder.getSaxEventList();if (saxEvents.isEmpty()) {addWarn("Empty sax event list");return;}// 2.根据xml节点的解析生成对应的model对象, top默认是configuration的modelModel top = buildModelFromSaxEventList(recorder.getSaxEventList());if (top == null) {addError(ErrorCodes.EMPTY_MODEL_STACK);return;}// 3.语法检查sanityCheck(top);// 4.解析model节点(核心)processModel(top);// no exceptions at this levelStatusUtil statusUtil = new StatusUtil(context);// 5.发布配置解析结束事件if (statusUtil.noXMLParsingErrorsOccurred(threshold)) {// xml解析无异常addInfo("Registering current configuration as safe fallback point");registerSafeConfiguration(top);context.fireConfigurationEvent(newConfigurationEndedSuccessfullyEvent(this));} else {// xml解析发生异常context.fireConfigurationEvent(newConfigurationEndedWithXMLParsingErrorsEvent(this));}}

方法小结

这里就是解析logback.xml的整个流程了, 编排了5个点

  1. populateSaxEventRecorder方法用来解析文件, 然后返回解析对象
  2. 根据解析logback.xml的结果生成对应的model
  3. 检查语法(不介绍)
  4. 解析model节点(核心)
  5. 发布解析完成事件(成功/失败)

logback.xml解析

populateSaxEventRecorder

public SaxEventRecorder populateSaxEventRecorder(final InputSource inputSource) throws JoranException {SaxEventRecorder recorder = new SaxEventRecorder(context);// sax解析配置文件, 每一个节点都会解析成SaxEvent, 分为StartEvent, BodyEvent, EndEventrecorder.recordEvents(inputSource);return recorder;
}

SaxEventRecorder

public class SaxEventRecorder extends DefaultHandler implements ContextAware {// 节点路径final ElementPath elementPath;// 解析节点得到的结果对象List<SaxEvent> saxEventList = new ArrayList<SaxEvent>();public void recordEvents(InputSource inputSource) throws JoranException {// 创建sax解析器SAXParser saxParser = buildSaxParser();try {// sax解析; 当前类SaxEventRecorder也是个DefaultHandlersaxParser.parse(inputSource, this);return;} catch (xxxException ie) {// ...异常处理}throw new IllegalStateException("This point can never be reached");}// 解析节点的起始标签public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {// ...}// 解析标签内容部分public void characters(char[] ch, int start, int length) {// ...}// 解析到标签结尾部分时触发public void endElement(String namespaceURI, String localName, String qName) {// ...   }
}

方法小结

  1. SaxEventRecorder对象用来封装解析logback.xml的逻辑, 同时它也是一个DefaultHandler对象, 负责处理每个节点的具体解析逻辑
  2. 使用sax解析logback.xml文件
  3. 每个节点解析结果存放在实例变量saxEventList中

关于常见的xml解析框架的对比如下

特性DOM4JSAXJSOUP
解析方式基于树模型,加载整个文档到内存基于事件驱动,逐行解析类似 DOM 树模型,专注于 HTML/XML
性能性能较高,但文件过大时内存消耗明显性能最高,适合大文件解析性能适中,适合中小型 XML 或 HTML 文档
内存占用较高,依赖于内存加载整个文档最低,仅在解析时占用较少内存较高,但通常适合处理网页等较小文件
功能支持强大的 XPath 支持,支持修改和生成 XML只支持读取,不能修改文档支持解析和修改文档,HTML/XML 均适用
易用性较高,API 友好较低,需要手动处理事件逻辑非常高,简洁的 API,类似 jQuery 操作
修改能力支持动态修改不支持修改支持动态修改,灵活度高
适用场景适合处理中小型 XML 文件适合处理超大文件或流式读取适合处理 HTML/XML 文件,尤其是网页解析
依赖性需要引入额外依赖(如 dom4j jar 包)无需额外依赖,Java 内置支持需要引入 jsoup jar 包
  • DOM4J:功能全面,支持 XPath,适合需要频繁修改 XML 的场景,但处理超大文件时会占用大量内存。

  • SAX:性能最佳,占用内存最少,适合超大文件的解析,但使用复杂且无法修改文档内容。

  • JSOUP:偏向网页内容解析,API 简单易用,支持 XML 和 HTML 的解析和修改,适合中小型文件处理。

通过SaxEvent构建节点model

buildModelFromSaxEventList

// 通过节点的saxEvent构建节点的model
public Model buildModelFromSaxEventList(List<SaxEvent> saxEvents) throws JoranException {// 构建saxEvent解析器buildSaxEventInterpreter(saxEvents);// 解析节点, 解析节点的顺序是StartEvent, BodyEvent, EndEvent, 最终使用playSaxEvents();Model top = saxEventInterpreter.getSaxEventInterpretationContext().peekModel();return top;
}// 构建saxEvent解析器, 并添加标签路径对应的action
protected void buildSaxEventInterpreter(List<SaxEvent> saxEvents) {// 1.创建ruleStore, 默认是SimpleRuleStoreRuleStore rs = getRuleStore();// 2.将路径和对应的解析对象action绑定addElementSelectorAndActionAssociations(rs);// 3.构建saxEvent解析器this.saxEventInterpreter = new SaxEventInterpreter(context, rs, initialElementPath(), saxEvents);// 给saxEvent解析器上下文添加contextSaxEventInterpretationContext interpretationContext = saxEventInterpreter.getSaxEventInterpretationContext();interpretationContext.setContext(context);// 4.给没有指定action的标签路径添加默认action; 这里是ImplicitModelAction, 用来解析ruleStore规则之外的标签, 给父标签对象添加属性用setImplicitRuleSupplier(saxEventInterpreter);
}

方法小结

  1. 创建ruleStore, 默认是SimpleRuleStore
  2. 将路径和对应的解析对象action绑定
  3. 构建saxEvent解析器
  4. 给没有指定action的标签路径添加默认action; 这里是ImplicitModelAction, 用来解析ruleStore规则之外的标签, 给父标签对象添加属性用

具体的解析逻辑在saxEvent解析器SaxEventInterpreter中, saxEvent经过action处理之后会得到对应标签节点的model对象

解析model节点

public void processModel(Model model) {// 1.创建ModelInterpretationContext并添加默认对象; 当一个标签没有指定class时, 会从这里尝试获取buildModelInterpretationContext();// configuration节点this.modelInterpretationContext.setTopModel(model);modelInterpretationContext.setConfiguratorHint(this);// 2.创建解析model的核心类DefaultProcessor defaultProcessor = new DefaultProcessor(context, this.modelInterpretationContext);// 3.将model与modelHandler和Analyser关联addModelHandlerAssociations(defaultProcessor);// disallow simultaneous configurations of the same contextReentrantLock configurationLock = context.getConfigurationLock();try {configurationLock.lock();// 开始解析modeldefaultProcessor.process(model);} finally {configurationLock.unlock();}
}

方法小结

  1. 构建model解析时的上下文ModelInterpretationContext, 并添加默认标签的class类(如下面的表格)
  2. 创建解析model的核心类DefaultProcessor
  3. 将model和对应的处理类(modelHandler)关联起来
  4. 使用DefaultProcessor解析model

默认标签的属性对应的类

通过buildModelInterpretationContext方法添加在ModelInterpretationContext.DefaultNestedComponentRegistry属性中

属性默认值
AppenderBaselayoutPatternLayout.class
UnsynchronizedAppenderBaselayoutPatternLayout.class
AppenderBaseencoderPatternLayoutEncoder
UnsynchronizedAppenderBaseencoderPatternLayoutEncoder
SSLComponentsslSSLConfiguration
SSLConfigurationparametersSSLParametersConfiguration
SSLConfigurationkeyStoreKeyStoreFactoryBean
SSLConfigurationtrustStoreKeyStoreFactoryBean
SSLConfigurationkeyManagerFactoryKeyManagerFactoryFactoryBean
SSLConfigurationtrustManagerFactoryTrustManagerFactoryFactoryBean
SSLConfigurationsecureRandomSecureRandomFactoryBean

例如下面的配置, 由于FileAppender是UnsynchronizedAppenderBase的子类, 并且encoder节点没有指定class, 而encoder是UnsynchronizedAppenderBase的一个属性, 所以这里取默认值PatternLayoutEncoder

<appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>logs/app.log</file><!-- encoder不指定class的时候, 默认使用的是PatternLayoutEncoder --><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern></encoder>
</appender>

我们常用的也就appender标签下的这两个layout和encoder属性

各标签节点路径以及其对应的model和modelHandler如下表格

一般情况下我们看节点路径和action以及handler就行, 这个handler就是用来处理logback.xml中各个标签的类。
这里的节点路径就是我们logback.xml文件中所有可以定义的节点了。

标签节点路径解析路径节点的Actionaction解析之后生成的model解析model的Handler
configurationConfigurationActionConfigurationModelConfigurationModelHandlerFull
configuration/contextNameContextNameActionContextNameModelContextNameModelHandler
configuration/contextListenerLoggerContextListenerActionLoggerContextListenerModelLoggerContextListenerModelHandler
configuration/insertFromJNDIInsertFromJNDIActionInsertFromJNDIModelInsertFromJNDIModelHandler
configuration/loggerLoggerActionLoggerModelLoggerModelHandler
configuration/logger/levelLevelActionLevelModelLevelModelHandler
configuration/rootRootLoggerActionRootLoggerModelRootLoggerModelHandler
configuration/root/levelRootLoggerActionRootLoggerModelRootLoggerModelHandler
configuration/logger/appender-refAppenderRefActionAppenderRefModelAppenderRefModelHandler
configuration/root/appender-refAppenderRefActionAppenderRefModelAppenderRefModelHandler
configuration/includeIncludeActionIncludeModelIncludeModelHandler
configuration/propertiesConfiguratorPropertiesConfiguratorActionPropertiesConfiguratorModelPropertiesConfiguratorModelHandler
configuration/consolePluginConsolePluginAction
configuration/receiverReceiverActionReceiverModelReceiverModelHandler
*/variablePropertyActionPropertyModelPropertyModelHandler
*/propertyPropertyActionPropertyModelPropertyModelHandler
configuration/importImportActionImportModelImportModelHandler
configuration/timestampTimestampActionTimestampModelTimestampModelHandler
configuration/shutdownHookShutdownHookActionShutdownHookModelShutdownHookModelHandler
configuration/sequenceNumberGeneratorSequenceNumberGeneratorActionSequenceNumberGeneratorModelSequenceNumberGeneratorModelHandler
configuration/serializeModelSerializeModelActionSerializeModelModelSerializeModelModelHandler
configuration/defineDefinePropertyActionDefineModelDefineModelHandler
configuration/evaluatorEventEvaluatorActionEventEvaluatorModelEventEvaluatorModelHandler
configuration/conversionRuleConversionRuleActionConversionRuleModelConversionRuleModelHandler
configuration/statusListenerStatusListenerActionStatusListenerModelStatusListenerModelHandler
*/appenderAppenderActionAppenderModelAppenderModelHandler
configuration/appender/appender-refAppenderRefActionAppenderRefModelAppenderRefModelHandler
configuration/newRuleNewRuleAction
*/paramParamActionParamModelParamModelHandler
*/ifIfActionIfModelIfModelHandler
*/if/thenThenActionThenModelThenModelHandler
*/if/elseElseActionElseModelElseModelHandler
*/appender/siftSiftActionSiftModelSiftModelHandler
其它属性标签ImplicitModelActionImplicitModelImplicitModelHandler

DefaultProcessor解析model

public void process(Model model) {// 根节点为空, 直接异常if (model == null) {addError("Expecting non null model to process");return;}// 1.将LoggerContext添加到ModelInterpretationContext中, 这是第一个也是最底层的initialObjectPush();// 2.使用第一阶段过滤器过滤model, 将满足条件的model使用handler处理mainTraverse(model, getPhaseOneFilter());// 3.处理依赖analyseDependencies(model);// 4.使用第二阶段过滤器过滤model, 将满足条件的model使用handler处理traversalLoop(this::secondPhaseTraverse, model, getPhaseTwoFilter(), "phase 2");// 配置解析完成addInfo("End of configuration.");// 5.将LoggerContext从ModelInterpretationContext中弹出finalObjectPop();
}

方法小结

  1. 将日志上下文loggerContext放到model解析器中
  2. 使用第一阶段过滤器过滤model, 将满足条件的model使用handler处理, 不满足第一阶段过滤器的model有下面四个, 为什么这四个model这么特殊呢?? 因为它们需要依赖别的model(appender-ref标签)
  • LoggerModel
  • RootLoggerModel
  • AppenderModel
  • AppenderRefModel
  1. 确定依赖顺序
  2. 使用第二阶段过滤器过滤model, 将满足条件的model使用handler处理; 上面四个model将会在这里处理
  3. 弹出loggerContext节点

具体的model节点解析将会在下节挑出几个重点来介绍, 到这里, logback解析logback.xml文件的整体流程就介绍完了

关于一些细节以及JoranConfigurator和JoranConfiguratorBase中相关的内容没有详细介绍, 读者想要了解的更多建议看下源码

三、总结

  1. JoranConfigurator 是logback框架用来解析配置文件的核心类(logback.xml配置文件)
  2. logback.xml文件中每个节点都会被解析成一个saxEvent, 解析过程中借助解析器上下文SaxEventInterpretationContext保存相关信息
  3. RuleStore中映射了每个节点路径对应的action, action会创建对应节点的model
  4. DefaultProcessor中记录了每个model和modelHandler的映射关系
  5. DefaultProcessor借助上下文对象ModelInterpretationContext将model分为两个阶段使用modelHandler进行处理
  6. 最后将处理结果都放到了日志上下文LoggerContext中(这是我们打印日志的重要对象)
  7. 流程就是(eg. configuration/appender/encoder -> saxEvent -> action -> model -> modelHandler -> loggerContext)

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

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

相关文章

leetcode刷题记录(七十八)——105. 从前序与中序遍历序列构造二叉树

&#xff08;一&#xff09;问题描述 105. 从前序与中序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09;105. 从前序与中序遍历序列构造二叉树 - 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一…

包文件分析器 Webpack Bundle Analyzer

webpack-bundle-analyzer 是一个非常有用的工具&#xff0c;用于可视化和分析 Webpack 打包生成的文件。这使得开发者能够更好地理解应用的依赖关系、包的大小&#xff0c;以及优化打包的机会。以下是关于 webpack-bundle-analyzer 的详细介绍&#xff0c;包括它的安装、使用以…

【PowerQuery专栏】PowerQuery提取XML数据

XML数据和Json 数据类型都是比较典型的层次数据类型,XML的数据格式非常的对称。所有的数据均是由标签对组成,图为典型的XML文件类型的数据。 在PowerQuery中进行XML数据类型解析采用的是Xml.Document 函数来进行文件内容的解析,Xml.Document 目前有三个可用参数。 参数1为数…

1.21学习记录

misc 2023isctf 你说爱我尊嘟假嘟 这题有点脑洞&#xff0c;需要把你说爱我换成Ook.将尊嘟换为Ook&#xff01;假嘟换成Ook&#xff1f;&#xff08;根据语气进行猜测吧&#xff09;用在线工具解密最后用base64解密即可 2023isctf 杰伦可是流量明星 解压后是一个MP3文件&am…

如何将自己本地项目开源到github上?

环境&#xff1a; LLMB项目 问题描述&#xff1a; 如何将自己本地项目开源到github上&#xff1f; 解决方案&#xff1a; 步骤 1: 准备本地项目 确保项目整洁 确认所有的文件都在合适的位置&#xff0c;并且项目的 README.md 文件已经完善。检查是否有敏感信息&#xff0…

【MySQL】数据库基础知识

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;【MySQL】数据库基础知识 发布时间&#xff1a;2025.1.21 隶属专栏&#xff1a;MySQL 目录 什么是数据库为什么要有数据库数据库的概念 主流数据库mysql的安装mysql登录使用一下mysql显示数据库内容创建一个数据库创…

使用插件SlideVerify实现滑块验证

作者gitee地址&#xff1a;https://gitee.com/monoplasty/vue-monoplasty-slide-verify 使用步骤&#xff1a; 1、安装插件 npm install --save vue-monoplasty-slide-verify 2、在main.js中进行配置 import SlideVerify from vue-monoplasty-slide-verify; Vue.use(SlideV…

Windows配置frp内网穿透实现远程连接

仅个人记录 本文仅介绍客户端的配置 1. 开始 frp分为服务端和客户端&#xff0c;为实现内网穿透需要同时配置服务端和客户端&#xff0c;并且版本保持一致&#xff0c;可以前往 frp github下载 本文使用 0.51.2 版本&#xff0c;从GitHub下载并解压&#xff0c;得到如下文件…

“大模型横扫千军”背后的大数据挖掘--浅谈MapReduce

文章目录 O 背景知识1 数据挖掘2 邦费罗尼原则3 TF.IDF4 哈希函数5 分布式文件系统 一、MapReduce基本介绍1. Map 任务2. 按键分组3. Reduce 任务4. 节点失效处理5.小测验&#xff1a;在一个大型语料库上有100个map任务和若干reduce任务&#xff1a; 二、基于MapReduce的基本运…

第17个项目:Python烟花秀

源码下载地址:https://download.csdn.net/download/mosquito_lover1/90295693 核心源码: import pygame import random import math from PIL import Image import io # 初始化pygame pygame.init() # 设置窗口 WIDTH = 800 HEIGHT = 600 screen = pygame.display.s…

JavaScript学习笔记(1)

html 完成了架子&#xff0c; css 做了美化&#xff0c;但是网页是死的&#xff0c;我们需要给他注入灵魂&#xff0c;所以接下来我们需要学习 JavaScript&#xff0c;这门语言会让我们的页面能够和用户进行交互。 一、引入方式 1.内部脚本 将 JS 代码定义在 HTML 页面中 Jav…

二十七、资源限制-LimitRange

LimitRange生产必备 在调度的时候 requests 比较重要,在运行时 limits 比较重要。 一、产生原因 生产中只有ResourceQuota是不够的 只配置ResourceQuotas的情况下,pod的yaml文件没有配置resources配置,都是0的话,就可以无限配置,永远达不到limit LimitRange做了什么 如…

docker部署的gitlab迁移

docker部署的gitlab迁移_docker gitlab 迁移-CSDN博客 gitlab-rake gitlab:backup:restore BACKUP 后面一路yes 生活中总是充满了各种选择&#xff0c;点餐纠结&#xff0c;出行选择&#xff0c;聚餐座位&#xff0c;团队投票结果不明&#xff0c;随机抽签一锤定音等等&#xf…

GS论文阅读--GeoTexDensifier

前言 本文是一个关于高斯致密化策略对高斯地图进行优化&#xff0c;他主要关注了几何结构和纹理信息。我最近对于高斯点的分布比较感兴趣&#xff0c;因为高斯点的分布决定了之后重建质量的好坏&#xff0c;初始化高斯很重要&#xff0c;但之后的维护需要致密化与修建策略&…

支持大功率输出高速频闪的图像处理用光源控制器

机器视觉系统中的光源控制器在确保图像质量、提高系统稳定性、降低能耗以及方便系统扩展和升级等方面发挥着重要作用。它可提供稳定光源&#xff0c;调节参数&#xff0c;另外具有操作便捷性。 下面我们来看Gardasoft的光源控制器&#xff0c;Gardasoft拥有作为图像处理用LED光…

Excel 技巧17 - 如何计算倒计时,以及数据条(★)

本文讲如何计算倒计时&#xff0c;以及加数据条。 1&#xff0c;如何计算倒计时 这里也要用公式 D3 - TODAY() 显示为下面这个样子的 然后右键该单元格&#xff0c;选 设置单元格格式 然后点 常规 这样就能显示出还书倒计时的日数了。 下拉适用到其他单元格。 2&#xff0c;…

springboot整合modbus实现通讯

springboot整合modbus4j实现tcp通讯 前言 本文基于springboot和modbus4j进行简单封装&#xff0c;达到开箱即用的目的&#xff0c;目前本方案仅实现了tcp通讯。代码会放在最后&#xff0c;按照使用方法操作后就可以直接使用 介绍 在使用本方案之前&#xff0c;有必要对modb…

iOS-YModel

YModel 是一个高效的 iOS/OSX 的模型转换框架&#xff0c;可以轻松地将 JSON 转换成 Model&#xff0c;或者将 Model 转换成 JSON。以下是详细的使用指南&#xff1a; 导入 YYModel: 确保在你的项目中导入了 YYModel。使用 CocoaPods 的话可以在 Podfile 中加入以下代码&#…

PhyCAGE:符合物理规律的图像到 3D 生成

Paper: Yan H, Zhang M, Li Y, et al. PhyCAGE: Physically Plausible Compositional 3D Asset Generation from a Single Image[J]. arXiv preprint arXiv:2411.18548, 2024. Introduction: https://wolfball.github.io/phycage/ Code: Unreleased PhyCAGE 是一种 image-to-3D…

麒麟操作系统服务架构保姆级教程(十三)tomcat环境安装以及LNMT架构

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 之前咱们学习了LNMP架构&#xff0c;但是PHP对于技术来说确实是老掉牙了&#xff0c;PHP的市场占有量越来越少了&#xff0c;我认识一个10年的PHP开发工程师&#xff0c;十年工资从15k到今天的6k&am…