SPRING10_getBean源碼詳細解讀、流程圖

文章目錄

  • ①. getBean方法的入口-DefaultListableBeanFactory
  • ②. DefaultListableBeanFactory調用getBean
  • ③. 進入到doGetBean方法
  • ④. getSingleton三級緩存方法
  • ⑤. getSingleton()方法分析
  • ⑥. createBean創建對象方法
  • ⑦. 對象創建、屬性賦值、初始化
  • ⑧. getBean最詳細流程圖

①. getBean方法的入口-DefaultListableBeanFactory

  • ①. getBean方法的入口:在Spring中,getBean方法的入口通常位于BeanFactory或ApplicationContext接口的實現類中。最常見的是DefaultListableBeanFactory類,它是Spring容器的核心實現,如下是三個API
// 根據name獲取bean	
@Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}// 根據name獲取bean,如果獲取到的bean和指定類型不匹配,則拋出異常
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);
}// 根據name獲取bean,如果是一個有參構造器生成的bean,則將參數對象注入到構造器中
@Override
public Object getBean(String name, Object... args) throws BeansException {return doGetBean(name, null, args, false);
}

在這里插入圖片描述

②. DefaultListableBeanFactory調用getBean

  • ②. DefaultListableBeanFactory中先獲取到所有的bean的名稱,for循環調用getBean方法
DefaultListableBeanFactorypublic void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 是非抽象的并且是單例的并且不是懶加載的if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 如果是FactoryBean執行下面邏輯(如果是實現了FactoryBean,isFactoryBean的標識為true)if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);// beanName = & + beanNameif (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {// 不是FactoryBean執行下面邏輯,普通的單實例非懶加載beangetBean(beanName);}}}
}
AbstractBeanFactory@Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}

③. 進入到doGetBean方法

  • ③. 進入到doGetBean方法
  1. transformedBeanName,處理別名BeanName、處理帶&符的工廠BeanName。
  2. getSingleton,先嘗試從緩存中獲取Bean實例,這個位置就是三級緩存解決循環依賴的方法(后面重點說)</font
  3. getObjectForBeanInstance,如果sharedInstance是普通的Bean實例,則下面的方法會直接返回。另外sharedInstance是工廠Bean類型,則需要獲取getObject方法,可以參考關于FactoryBean的實現類。
  4. isPrototypeCurrentlyInCreation,循環依賴有三種,setter注入、多實例和構造函數,Spring只能解決setter注入,所以這里是Prototype則會拋出異常。
  5. getParentBeanFactory,父bean工廠存在,當前bean不存在于當前bean工廠,則到父工廠查找bean實例。
  6. mbd.getDependsOn,處理使用了depends-on注解的依賴創建bean實例。getBean(dep),加載depends-on依賴dep是depends-on縮寫
  7. mbd.isSingleton(),創建單例bean實例,這里的sharedInstance = getSingleton(beanName, () -> {})很重要</font
  8. mbd.isPrototype(),創建其他類型的bean實例
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {//處理別名BeanName、處理帶&符的工廠BeanName,工廠beanName帶了&xxx 最后會變成xxxString beanName = transformedBeanName(name);Object beanInstance;// Eagerly check singleton cache for manually registered singletons.// 先檢查單實例bean緩存Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {//默認第一次獲取組件都會進入到else環節,如果第一次獲取肯定是沒有的// Fail if we're already creating this bean instance:// We're assumably within a circular reference.// 如果是一個多實例bean,拋出異常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 拿到整個bean工廠,拿到父工廠;看父工廠有沒有,如果有從父工廠去獲取 Check if bean definition exists in this factory.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {// 標記當前bean已經被創建,用來阻止多線程引用的markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// 看有沒有依賴其他Bean,如果有先獲取其他的那個Beanfor (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance. 創建Bean試連if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});// 看當前bean是否是使用了beanFactorybeanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ′" + beanName + "'");}Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end();}}return adaptBeanInstance(name, beanInstance, requiredType);
}

④. getSingleton三級緩存方法

  • ④. Object sharedInstance = getSingleton(beanName,第一次進來的時候,會直接返回null
  1. 一級緩存 - singletonObjects
  2. 二級緩存 - earlySingletonObjects,當前bean已經創建,未進行實例化
  3. 三級緩存 - singletonFactories,用來保存BeanName和創建bean的工廠之間的關系
	/** * 一級緩存* Cache of singleton objects: bean name --> bean instance */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** * 三級緩存* 用來保存BeanName和創建bean的工廠之間的關系* Cache of singleton factories: bean name --> ObjectFactory */private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/** * 二級緩存* 保存BeanName和創建bean實例之間的關系,與singletonFactories的不同之處在于,當一個單例bean被放到這里之后,那么當bean還在創建過程中* 就可以通過getBean方法獲取到,可以方便進行循環依賴的檢測* Cache of early singleton objects: bean name --> bean instance */private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);public Object getSingleton(String beanName) { // allowEarlyReference 允許早期引用(循環依賴的核心)return getSingleton(beanName, true);}@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// 先檢查單列緩存池,獲取當前對象 Quick check for existing instance without full singleton lockObject singletonObject = this.singletonObjects.get(beanName);// 先看單例池有沒有 并且 是否正在創建if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {// 如果當前bean正在創建過程中,而且緩存中沒有繼續往下//singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}

⑤. getSingleton()方法分析

  • ⑤. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法
  1. beforeSingletonCreation(beanName)會將beanName加入到singletonsCurrentlyInCreation集合中去,表示正在創建的集合
  2. singletonFactory.getObject()會調用lamda表達式的內容[這里之后要進入lamda方法流程]
  3. afterSingletonCreation(beanName)會將當前beanName從singletonsCurrentlyInCreation中移除出去
  4. addSingleton方法會將當前bean加入到singletonObjects池中去
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {// 會調用lamda表達式的內容singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime ->// if yes, proceed with it since the exception indicates that state.singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}afterSingletonCreation(beanName);}if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}

⑥. createBean創建對象方法

  • ⑥. 進入到createBean(beanName, mbd, args);lamda流程,最重要的是doCreateBean方法,進入到創建對象流程中
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// 提前給一個機會,去返回組件的代理對象(aop也沒有在這里操作) Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}......Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}

⑦. 對象創建、屬性賦值、初始化

  • ⑦. doCreateBean方法詳解
  1. 利用無參構造方法創建實例
  2. earlySingletonExposure表示:當前對象是單實列、并且singletonsCurrentlyInCreation中存在這個beanName,我們在上面的步驟中已經加入到了singletonsCurrentlyInCreation集合中了
  3. addSingletonFactory方法會將beanName加入到三級緩存singletonFactories中去
  4. populateBean進行屬性的賦值,@Autowired發生在這里
  5. initializeBean初始化bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {//是否單例instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 創建Bean的實列,默認使用無參構造創建對象instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}//允許MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition再來修改下BeanDefinition Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {// 給創建好的對象每個屬性進行賦值,@Autowired發生在這里populateBean(beanName, mbd, instanceWrapper);// 初始化beanexposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}

⑧. getBean最詳細流程圖

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896015.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IDEA中查詢Maven項目的依賴樹

在Maven項目中&#xff0c;查看項目的依賴樹是一個常見的需求&#xff0c;特別是當你需要了解項目中直接或間接依賴了哪些庫及其版本時。你可以通過命令行使用Maven的dependency:tree插件來做到這一點。這個命令會列出項目中所有依賴的樹狀結構。 打開idea項目的終端&#xff…

深入xtquant:財務數據獲取與應用的實戰指南

深入xtquant&#xff1a;財務數據獲取與應用的實戰指南 在量化交易領域&#xff0c;雖然技術分析和市場情緒分析占據了主導地位&#xff0c;但財務數據作為評估公司基本面的重要依據&#xff0c;同樣不可或缺。xtquant作為一個強大的Python庫&#xff0c;提供了便捷的接口來獲…

windows 安裝 stable diffusion

在windows上安裝 stable diffusion&#xff0c;如果windows沒有nvidia顯卡&#xff0c;想只使用CPU可在webui-user.bat中添加命令 set COMMANDLINE_ARGS--no-half --skip-torch-cuda-test 可正常使用stable diffusion&#xff0c;但速度較慢

Kubernetes控制平面組件:APIServer 基于 引導Token 的認證機制

云原生學習路線導航頁&#xff08;持續更新中&#xff09; kubernetes學習系列快捷鏈接 Kubernetes架構原則和對象設計&#xff08;一&#xff09;Kubernetes架構原則和對象設計&#xff08;二&#xff09;Kubernetes架構原則和對象設計&#xff08;三&#xff09;Kubernetes控…

DeepSeek 助力 Vue 開發:打造絲滑的縮略圖列表(Thumbnail List)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 Deep…

DeepSeek寫俄羅斯方塊手機小游戲

DeepSeek寫俄羅斯方塊手機小游戲 提問 根據提的要求&#xff0c;讓DeepSeek整理的需求&#xff0c;進行提問&#xff0c;內容如下&#xff1a; 請生成一個包含以下功能的可運行移動端俄羅斯方塊H5文件&#xff1a; 核心功能要求 原生JavaScript實現&#xff0c;適配手機屏幕 …

百問網(100ask)的IMX6ULL開發板的以太網控制器(MAC)與物理層(PHY)芯片(LAN8720A)連接的原理圖分析(包含各引腳說明以及工作原理)

前言 本博文承接博文 https://blog.csdn.net/wenhao_ir/article/details/145663029 。 本博文和博文 https://blog.csdn.net/wenhao_ir/article/details/145663029 的目錄是找出百問網(100ask)的IMX6ULL開發板與NXP官方提供的公板MCIMX6ULL-EVK(imx6ull14x14evk)在以太網硬件…

QT開發技術 【opencv圖片裁剪,平均哈希相似度判斷,以及獲取游戲窗口圖片】

一、圖片裁剪 int CJSAutoWidget::GetHouseNo(cv::Mat matMap) {cv::imwrite(m_strPath "/Data/map.png", matMap);for (int i 0; i < 4; i){for (int j 0; j < 6; j){// 計算當前子區域的矩形cv::Rect roi(j * 20, i * 17, 20, 17);// 提取子區域cv::Mat …

TiDB 是一個分布式 NewSQL 數據庫

TiDB 是一個分布式 NewSQL 數據庫。它支持水平彈性擴展、ACID 事務、標準 SQL、MySQL 語法和 MySQL 協議&#xff0c;具有數據強一致的高可用特性&#xff0c;是一個不僅適合 OLTP 場景還適合 OLAP 場景的混合數據庫。 TiDB是 PingCAP公司自主設計、研發的開源分布式關系型數據…

請解釋 Vue 中的生命周期鉤子,不同階段觸發的鉤子函數及其用途是什么?

vue生命周期鉤子詳解&#xff08;Vue 3版本&#xff09; 一、生命周期階段劃分 Vue組件的生命周期可分為四大階段&#xff0c;每個階段對應特定鉤子函數&#xff1a; 創建階段&#xff1a;初始化實例并準備數據掛載階段&#xff1a;將虛擬DOM渲染為真實DOM更新階段&#xff…

計算機專業知識【深入理解子網中的特殊地址:為何 192.168.0.1 和 192.168.0.255 不能隨意分配】

在計算機網絡的世界里&#xff0c;IP 地址是設備進行通信的關鍵標識。對于常見的子網&#xff0c;如 192.168.0.0/24&#xff0c;我們可能會疑惑為何某些地址不能分配給主機使用。接下來&#xff0c;我們就以 192.168.0.0/24 為例&#xff0c;詳細解釋為何 192.168.0.1 和 192.…

軟件架構設計:軟件工程

一、軟件工程概述 軟件工程的定義 軟件工程是應用系統化、規范化、可量化的方法開發、運行和維護軟件。 軟件工程的目標 提高軟件質量、降低開發成本、縮短開發周期。 軟件生命周期 瀑布模型&#xff1a;需求分析→設計→編碼→測試→維護。迭代模型&#xff1a;分階段迭代開…

mysql 學習15 SQL優化,插入數據優化,主鍵優化,order by優化,group by 優化,limit 優化,count 優化,update 優化

插入數據優化&#xff0c; insert 優化&#xff0c; 批量插入&#xff08;一次不超過1000條&#xff09; 手動提交事務 主鍵順序插入 load 從本地一次插入大批量數據&#xff0c; 登陸時 mysql --local-infile -u root -p load data local infile /root/sql1.log into table tb…

達夢數據庫針對慢SQL,收集統計信息清除執行計劃緩存

前言&#xff1a;若遇到以下場景&#xff0c;大概率是SQL走錯了執行計劃&#xff1a; 1、一條SQL在頁面上查詢特別慢&#xff0c;但拿到數據庫終端執行特別快 2、一條SQL在某種檢索條件下查詢特別慢&#xff0c;但拿到數據庫終端執行特別快 此時&#xff0c;可以嘗試按照下述步…

使用JWT實現微服務鑒權

目錄 一、微服務鑒權 1、思路分析 2、系統微服務簽發token 3、網關過濾器驗證token 4、測試鑒權功能 前言&#xff1a; 隨著微服務架構的廣泛應用&#xff0c;服務間的鑒權與安全通信成為系統設計的核心挑戰之一。傳統的集中式會話管理在分布式場景下面臨性能瓶頸和擴展性…

廣西壯族自治區園區投促中心黨委書記陶德文率團到訪深蘭科技

2月16日&#xff0c;廣西壯族自治區園區投促中心黨委書記、主任&#xff0c;自治區園區辦黨組成員陶德文率團來到深蘭科技集團上海總部考察調研&#xff0c;并與深蘭科技集團創始人、董事長陳海波等集團管理層座談交流&#xff0c;雙方圍繞深蘭科技人工智能項目落地廣西的相關事…

基于UnrealEngine(UE5)的太空探索

視頻部分可參見&#xff1a;https://www.bilibili.com/video/BV1JWA8eSEVg/ 中國 天宮號 空間站 人造衛星可視化 星鏈衛星可視化 小行星分布及運動軌跡可視化 月球基地 可視化 八大行星軌道 太陽系宜居帶可視化 阿波羅8號拍攝的地球升起 谷神星模型及軌跡可視化 星座可視化 十…

WLAN無線2.4G/5G頻段劃分和可用信道

互聯網各領域資料分享專區(不定期更新)&#xff1a; Sheet

使用 OpenTelemetry 和 Langtrace 的 Elastic 分發跟蹤基于 RAG 的聊天機器人

作者&#xff1a;來自 Elastic Bahubali Shetti 如何使用 Elastic 觀察基于 OpenAI RAG 的應用程序。使用 Langtrace 對應用程序進行檢測&#xff0c;收集日志、跟蹤、指標&#xff0c;并了解 LLM 在 Kubernetes 上使用 OpenTelemetry 的 Elastic Distributions 的運行情況。 目…