<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖文并茂,Spring Boot Starter 萬(wàn)字詳解!還有誰(shuí)不會(huì)?

          共 10892字,需瀏覽 22分鐘

           ·

          2021-12-23 00:15


          來(lái)源:blog.csdn.net/qq_21310939/article/details/107401400

          • 一、SpringBoot的starter簡(jiǎn)介
            • 1.1 什么是starter(場(chǎng)景啟動(dòng)器)
          • 二、SpringBoot場(chǎng)景啟動(dòng)器的原理
            • 2.1 自動(dòng)配置原理
            • 2.2 SpringBoot自動(dòng)配置使用總結(jié)
          • 三、自定義場(chǎng)景啟動(dòng)器
            • 3.1 starter的命名規(guī)范
            • 3.2 starter模塊整體結(jié)構(gòu)
            • 3.3 autoconfigure模塊開(kāi)發(fā)
            • 3.4 Starter模塊開(kāi)發(fā)



          一、SpringBoot的starter簡(jiǎn)介

          1.1 什么是starter(場(chǎng)景啟動(dòng)器)

          在SpringBoot出現(xiàn)之前,如果我們想使用SpringMVC來(lái)構(gòu)建我們的web項(xiàng)目,必須要做的幾件事情如下:

          • 首先項(xiàng)目中需要引入SpringMVC的依賴(lài)
          • 在web.xml中注冊(cè)SpringMVC的DispatcherServlet,并配置url映射
          • 編寫(xiě)springmcv-servlet.xml,在其中配置SpringMVC中幾個(gè)重要的組件,處理映射器(HandlerMapping)、處理適配器(HandlerAdapter)、視圖解析器(ViewResolver)
          • applicationcontext.xml文件中引入springmvc-servlet.xml文件

          以上這幾步只是配置好了SpringMVC,如果我們還需要與數(shù)據(jù)庫(kù)進(jìn)行交互,就要在application.xml中配置數(shù)據(jù)庫(kù)連接池DataSource,如果需要數(shù)據(jù)庫(kù)事務(wù),還需要配置TransactionManager…

          這就是使用Spring框架開(kāi)發(fā)項(xiàng)目帶來(lái)的一些的問(wèn)題:

          • 依賴(lài)導(dǎo)入問(wèn)題: 每個(gè)項(xiàng)目都需要來(lái)單獨(dú)維護(hù)自己所依賴(lài)的jar包,在項(xiàng)目中使用到什么功能就需要引入什么樣的依賴(lài)。手動(dòng)導(dǎo)入依賴(lài)容易出錯(cuò),且無(wú)法統(tǒng)一集中管理
          • 配置繁瑣: 在引入依賴(lài)之后需要做繁雜的配置,并且這些配置是每個(gè)項(xiàng)目來(lái)說(shuō)都是必要的,例如web.xml配置(Listener配置、Filter配置、Servlet配置)、log4j配置、數(shù)據(jù)庫(kù)連接池配置等等。這些配置重復(fù)且繁雜,在不同的項(xiàng)目中需要進(jìn)行多次重復(fù)開(kāi)發(fā),這在很大程度上降低了我們的開(kāi)發(fā)效率

          而在SpringBoot出現(xiàn)之后,它為我們提供了一個(gè)強(qiáng)大的功能來(lái)解決上述的兩個(gè)痛點(diǎn),這就是SpringBoot的starters(場(chǎng)景啟動(dòng)器)。

          Spring Boot通過(guò)將我們常用的功能場(chǎng)景抽取出來(lái),做成的一系列場(chǎng)景啟動(dòng)器,這些啟動(dòng)器幫我們導(dǎo)入了實(shí)現(xiàn)各個(gè)功能所需要依賴(lài)的全部組件,我們只需要在項(xiàng)目中引入這些starters,相關(guān)場(chǎng)景的所有依賴(lài)就會(huì)全部被導(dǎo)入進(jìn)來(lái),并且我們可以?huà)仐壏彪s的配置,僅需要通過(guò)配置文件來(lái)進(jìn)行少量的配置就可以使用相應(yīng)的功能。

          二、SpringBoot場(chǎng)景啟動(dòng)器的原理

          在導(dǎo)入的starter之后,SpringBoot主要幫我們完成了兩件事情:

          • 相關(guān)組件的自動(dòng)導(dǎo)入
          • 相關(guān)組件的自動(dòng)配置

          這兩件事情統(tǒng)一稱(chēng)為SpringBoot的自動(dòng)配置

          2.1 自動(dòng)配置原理

          2.1.1 自動(dòng)配置類(lèi)的獲取與注入

          我們從主程序入口來(lái)探索一下整個(gè)過(guò)程的原理:

          @SpringBootApplication?//標(biāo)注這個(gè)類(lèi)是一個(gè)springboot的應(yīng)用
          public?class?CommunityApplication?{
          ????public?static?void?main(String[]?args)?{
          ????????//將springboot應(yīng)用啟動(dòng)
          ????????SpringApplication.run(CommunityApplication.class,?args);
          ????}
          }

          @SpringBootApplication注解內(nèi)部結(jié)構(gòu)如下圖所示:

          AutoConfigurationImportSelector :重點(diǎn)看該類(lèi)中重寫(xiě)的selectImports方法,看下它返回的字符串?dāng)?shù)組是如何得來(lái)的:

          我們可以去到上邊提到的spring.factories文件中去看一下,找到spring官方提供的spring-boot-autoconfigure包,在其下去找一下該文件:

          可以看到這個(gè)就是SpringBoot官方為我們提供的所有自動(dòng)配置類(lèi)的候選列表。我們可以在其中找到一個(gè)我們比較熟悉的自動(dòng)配置類(lèi)去看一下它內(nèi)部的實(shí)現(xiàn):

          可以看到這些一個(gè)個(gè)的都是JavaConfig配置類(lèi),而且都通過(guò)@Bean注解向容器中注入了一些Bean。

          結(jié)論:

          • SpringBoot在啟動(dòng)的時(shí)候從類(lèi)路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的所有自動(dòng)配置類(lèi)的全限定類(lèi)名
          • 將這些自動(dòng)配置類(lèi)導(dǎo)入容器,自動(dòng)配置類(lèi)就生效,幫我們進(jìn)行自動(dòng)配置工作;
          • 整個(gè)J2EE的整體解決方案和自動(dòng)配置都在spring-boot-autoconfigure的jar包中;
          • 它會(huì)給容器中導(dǎo)入非常多的自動(dòng)配置類(lèi) (xxxAutoConfiguration), 就是給容器中導(dǎo)入這個(gè)場(chǎng)景需要的所有組件,并配置好這些組件 ;
          • 有了自動(dòng)配置類(lèi),免去了我們手動(dòng)編寫(xiě)配置注入功能組件等的工作;

          2.1.2 自動(dòng)配置的過(guò)程

          自動(dòng)配置類(lèi)被注入到容器當(dāng)中后,會(huì)幫我們進(jìn)行組件的自動(dòng)配置和自動(dòng)注入的工作,我們以HttpEncodingAutoConfiguration(Http編碼自動(dòng)配置)為例解釋這個(gè)過(guò)程:

          首先我們先看下SpringBoot中配置文件與POJO類(lèi)之間映射的方法,這是進(jìn)行自動(dòng)配置的基礎(chǔ)。

          配置集中化管理:SpringBoot中所有可配置項(xiàng)都集中在一個(gè)文件中(application.yml),這個(gè)文件中的配置通過(guò)@ConfigurationProperties注解來(lái)與我們程序內(nèi)部定義的POJO類(lèi)來(lái)產(chǎn)生關(guān)聯(lián),這些POJO類(lèi)統(tǒng)一命名為xxxProperties,并且這些xxxProperties類(lèi)中各個(gè)屬性字段都有自己的默認(rèn)值,這也是SpringBoot約定大于配置理念的體現(xiàn),盡可能減少用戶(hù)做選擇的次數(shù),但同時(shí)又不失靈活性。只要我們想,配置文件中的配置隨時(shí)可以覆蓋默認(rèn)值。

          之后,通過(guò)配合@EnableConfigurationProperties注解,就可以自動(dòng)將與配置文件綁定好的這個(gè)類(lèi)注入到容器中供我們使用。

          自動(dòng)配置類(lèi)的工作流程:

          • 根據(jù)限定的條件向容器中注入組件
          • 使用xxxProperties對(duì)注入的組件的相關(guān)屬性進(jìn)行配置
          //表示這是一個(gè)配置類(lèi),和以前編寫(xiě)的配置文件一樣,也可以給容器中添加組件;
          @Configuration

          //將與配置文件綁定好的某個(gè)類(lèi)注入到容器中,使其生效
          //進(jìn)入這個(gè)HttpProperties查看,將配置文件中對(duì)應(yīng)的值和HttpProperties綁定起來(lái);
          //并把HttpProperties加入到ioc容器中
          @EnableConfigurationProperties(HttpProperties.class)

          //Spring底層@Conditional注解
          //根據(jù)不同的條件判斷,如果滿(mǎn)足指定的條件,整個(gè)配置類(lèi)里面的配置就會(huì)生效;
          //這里的意思就是判斷當(dāng)前應(yīng)用是否是web應(yīng)用,如果是,當(dāng)前配置類(lèi)生效
          @ConditionalOnWebApplication(type?
          =?ConditionalOnWebApplication.Type.SERVLET)

          //判斷系統(tǒng)中有沒(méi)有CharacterEncodingFilter這個(gè)類(lèi),如果有配置類(lèi)才生效
          @ConditionalOnClass(CharacterEncodingFilter.class)

          //判斷配置文件中是否存在某個(gè)配置:spring.http.encoding.enabled;
          //matchIfMissing?
          =?true表明即使我們配置文件中不配置pring.http.encoding.enabled=true,該配置類(lèi)也是默認(rèn)生效的;
          @ConditionalOnProperty(prefix?=?"spring.http.encoding",?value?=?"enabled",?matchIfMissing?=?true)
          public?class?HttpEncodingAutoConfiguration?{

          ??//該類(lèi)已經(jīng)與配置文件綁定了
          ?private?final?HttpProperties.Encoding?properties;

          ??//構(gòu)建該自動(dòng)配置類(lèi)時(shí)將與配置文件綁定的配置類(lèi)作為入?yún)鬟f進(jìn)去
          ?public?HttpEncodingAutoConfiguration(HttpProperties?properties)?{
          ??this.properties?=?properties.getEncoding();
          ?}

          ?@Bean
          ?@ConditionalOnMissingBean
          ?public?CharacterEncodingFilter?characterEncodingFilter()?{
          ??CharacterEncodingFilter?filter?=?new?OrderedCharacterEncodingFilter();
          ??filter.setEncoding(this.properties.getCharset().name());?//注入bean時(shí)使用配置類(lèi)中屬性的值進(jìn)行初始化,相當(dāng)于將配置文件中的值映射到了組件的某些屬性上
          ??filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
          ??filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
          ??return?filter;?//注入配置好的bean
          ?}
          }

          一句話(huà)總結(jié)下自動(dòng)配置類(lèi)的工作過(guò)程 :

          • 首先容器會(huì)根據(jù)當(dāng)前不同的條件判斷,決定這個(gè)配置類(lèi)是否生效!
          • 一但這個(gè)配置類(lèi)生效;這個(gè)配置類(lèi)就會(huì)給容器中添加相應(yīng)組件;
          • 這些組件的屬性是從對(duì)應(yīng)的properties類(lèi)中獲取的,這些類(lèi)里面的每一個(gè)屬性又是和配置文件綁定的;
          • 所有在配置文件中能配置的屬性都是在xxxxProperties類(lèi)中封裝著,配置文件可以配置什么內(nèi)容,可以參照該前綴對(duì)應(yīng)的屬性類(lèi)中的屬性字段
          //從配置文件中獲取指定的值和bean的屬性進(jìn)行綁定
          @ConfigurationProperties(prefix?=?"spring.http")
          public?class?HttpProperties?{
          ????//?.....
          }

          2.2 SpringBoot自動(dòng)配置使用總結(jié)

          • SpringBoot啟動(dòng)會(huì)加載大量的自動(dòng)配置類(lèi)

          • 我們首先可以看我們需要的功能有沒(méi)有在SpringBoot默認(rèn)寫(xiě)好的自動(dòng)配置類(lèi)當(dāng)中;

          • 我們?cè)賮?lái)看這個(gè)自動(dòng)配置類(lèi)中到底配置了哪些組件;(只要我們要用的組件存在在其中,我們就不需要再手動(dòng)配置了)

          • 給容器中自動(dòng)配置類(lèi)添加組件的時(shí)候,會(huì)從properties類(lèi)中獲取某些屬性。我們只需要在配置文件中指定這些屬性的值即可;

            • xxxxAutoConfigurartion:自動(dòng)配置類(lèi);給容器中添加組件
            • xxxxProperties:封裝配置文件中相關(guān)屬性;

          了解完自動(dòng)裝配的原理后,我們來(lái)關(guān)注一個(gè)細(xì)節(jié)問(wèn)題,自動(dòng)配置類(lèi)必須在一定的條件下才能生效;@Conditional派生注解(Spring注解版原生的@Conditional作用)

          作用:必須是@Conditional指定的條件成立,才給容器中添加組件,配置里面的所有內(nèi)容才生效;

          @Conditional擴(kuò)展注解作用(判斷是否滿(mǎn)足當(dāng)前條件)
          @ConditionalOnNotWebApplication當(dāng)前不是web環(huán)境
          @ConditionalOnWebApplication當(dāng)前是web環(huán)境
          @ConditionalOnResource類(lèi)路徑下是否有指定資源文件
          @ConditionalOnExpression滿(mǎn)足SpEL表達(dá)式指定
          @ConditionalOnMissingBean容器中不存在指定的Bean
          @ConditionalOnBean容器中是否存在指定的Bean
          @ConditionalOnSingleCandidate容器中只有一個(gè)指定的Bean,或者這個(gè)Bean是首選Bean
          @ConditionalOnJava系統(tǒng)的java版本是否符合要求
          @ConditionalOnMissingClass系統(tǒng)中沒(méi)有指定的類(lèi)
          @ConditionalOnClass系統(tǒng)中有指定的類(lèi)
          @ConditionalOnProperty系統(tǒng)中指定的屬性是否有指定的值

          那么多的自動(dòng)配置類(lèi),必須在一定的條件下才能生效;也就是說(shuō),我們加載了這么多的配置類(lèi),但不是所有的都生效了。

          我們?cè)趺粗滥男┳詣?dòng)配置類(lèi)生效?

          我們可以通過(guò)啟用 debug=true屬性;來(lái)讓控制臺(tái)打印自動(dòng)配置報(bào)告,這樣我們就可以很方便的知道哪些自動(dòng)配置類(lèi)生效;

          #在配置文件中開(kāi)啟springboot的調(diào)試類(lèi)
          debug=true

          Positive matches:(自動(dòng)配置類(lèi)啟用的:正匹配)

          Positive?matches:
          -----------------

          ???AopAutoConfiguration?matched:
          ??????-?@ConditionalOnClass?found?required?classes?'org.springframework.context.annotation.EnableAspectJAutoProxy',?'org.aspectj.lang.annotation.Aspect',?'org.aspectj.lang.reflect.Advice',?'org.aspectj.weaver.AnnotatedElement'?(OnClassCondition)
          ??????-?@ConditionalOnProperty?(spring.aop.auto=true)?matched?(OnPropertyCondition)

          ???AopAutoConfiguration.CglibAutoProxyConfiguration?matched:
          ??????-?@ConditionalOnProperty?(spring.aop.proxy-target-class=true)?matched?(OnPropertyCondition)

          ???AuditAutoConfiguration#auditListener?matched:
          ??????-?@ConditionalOnMissingBean?(types:?org.springframework.boot.actuate.audit.listener.AbstractAuditListener;?SearchStrategy:?all)?did?not?find?any?beans?(OnBeanCondition)

          ???AuditAutoConfiguration#authenticationAuditListener?matched:
          ??????-?@ConditionalOnClass?found?required?class?'org.springframework.security.authentication.event.AbstractAuthenticationEvent'?(OnClassCondition)
          ??????-?@ConditionalOnMissingBean?(types:?org.springframework.boot.actuate.security.AbstractAuthenticationAuditListener;?SearchStrategy:?all)?did?not?find?any?beans?(OnBeanCondition)

          Negative matches:(沒(méi)有啟動(dòng),沒(méi)有匹配成功的自動(dòng)配置類(lèi):負(fù)匹配)

          Negative?matches:
          -----------------

          ???ActiveMQAutoConfiguration:
          ??????Did?not?match:
          ?????????-?@ConditionalOnClass?did?not?find?required?class?'javax.jms.ConnectionFactory'?(OnClassCondition)

          ???AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:
          ??????Did?not?match:
          ?????????-?@ConditionalOnProperty?(spring.aop.proxy-target-class
          =false)?did?not?find?property?'proxy-target-class'?(OnPropertyCondition)

          ???AppOpticsMetricsExportAutoConfiguration:
          ??????Did?not?match:
          ?????????-?@ConditionalOnClass?did?not?find?required?class?'io.micrometer.appoptics.AppOpticsMeterRegistry'?(OnClassCondition)

          ???ArtemisAutoConfiguration:
          ??????Did?not?match:
          ?????????-?@ConditionalOnClass?did?not?find?required?class?'javax.jms.ConnectionFactory'?(OnClassCondition)

          Exclusions、Unconditional classes(排除的、沒(méi)有限定條件的自動(dòng)配置類(lèi)):

          Exclusions:
          -----------

          ????org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

          Unconditional?classes:
          ----------------------

          ????org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

          ????org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration

          ????org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration

          ????org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration

          推薦下自己做的 Spring Cloud 的實(shí)戰(zhàn)項(xiàng)目:

          https://github.com/YunaiV/onemall

          三、自定義場(chǎng)景啟動(dòng)器

          現(xiàn)在我們已經(jīng)了解了場(chǎng)景啟動(dòng)器的概念以及其隱藏在背后的自動(dòng)配置的原理,我們就可以自己來(lái)對(duì)SpringBoot進(jìn)行功能拓展,定義我們自己的場(chǎng)景啟動(dòng)器。

          3.1 starter的命名規(guī)范

          官方命名空間

          • 前綴:spring-boot-starter-
          • 模式:spring-boot-starter-模塊名
          • 舉例:spring-boot-starter-web、spring-boot-starter-jdbc

          自定義命名空間

          • 后綴:-spring-boot-starter
          • 模式:模塊-spring-boot-starter
          • 舉例:mybatis-spring-boot-starter

          3.2 starter模塊整體結(jié)構(gòu)

          通過(guò)上邊的介紹,可以總結(jié)starter的整體實(shí)現(xiàn)邏輯主要由兩個(gè)基本部分組成:

          xxxAutoConfiguration:自動(dòng)配置類(lèi),對(duì)某個(gè)場(chǎng)景下需要使用到的一些組件進(jìn)行自動(dòng)注入,并利用xxxProperties類(lèi)來(lái)進(jìn)行組件相關(guān)配置

          xxxProperties:某個(gè)場(chǎng)景下所有可配置屬性的集成,在配置文件中配置可以進(jìn)行屬性值的覆蓋 按照SpringBoot官方的定義,Starer的作用就是依賴(lài)聚合,因此直接在starter內(nèi)部去進(jìn)行代碼實(shí)現(xiàn)是不符合規(guī)定的,starter應(yīng)該只起到依賴(lài)導(dǎo)入的作用,而具體的代碼實(shí)現(xiàn)應(yīng)該去交給其他模塊來(lái)實(shí)現(xiàn),然后在starter中去引用該模塊即可,因此整體的starter的構(gòu)成應(yīng)該如下圖所示:

          可見(jiàn)starter模塊依賴(lài)了兩部分,一部分是一些常用依賴(lài),另一部分就是對(duì)自動(dòng)配置模塊的依賴(lài),而xxxAutoConfigurationxxxProperties的具體實(shí)現(xiàn),都封裝在自動(dòng)配置模塊中,starter實(shí)際是通過(guò)該模塊來(lái)對(duì)外提供相應(yīng)的功能。

          3.3 autoconfigure模塊開(kāi)發(fā)

          3.3.1 依賴(lài)引入

          首先所有的自動(dòng)配置模塊都要引入兩個(gè)jar包依賴(lài):

          <dependencies>
          ?????<dependency>
          ?????????<groupId>org.springframework.bootgroupId>
          ?????????<artifactId>spring-boot-autoconfigureartifactId>
          ????????
          ?????dependency>
          ?????<dependency>
          ?????????<groupId>org.springframework.bootgroupId>
          ?????????<artifactId>spring-boot-configuration-processorartifactId>
          ???????
          ?????????<optional>trueoptional>
          ?????dependency>
          ?<dependencies>

          其他依賴(lài)的選擇根據(jù)項(xiàng)目需要進(jìn)行添加即可。

          3.3.2 xxxAutoConfiguration的實(shí)現(xiàn)

          autoconfigure模塊中最重要的就是自動(dòng)配置類(lèi)的編寫(xiě),它為我們實(shí)現(xiàn)組件的自動(dòng)配置與自動(dòng)注入。

          在編寫(xiě)自動(dòng)配置類(lèi)的時(shí)候,我們應(yīng)該要考慮向容器中注入什么組件,如何去配置它。

          @Configuration
          @ConditionalOnxxx
          @ConditionalOnxxx//限定自動(dòng)配置類(lèi)生效的一些條件
          @EnableConfigurationProperties(xxxProperties.class)
          public?class?xxxAutoConfiguration?
          {
          ?@Autowired
          ?private?xxxProperties?properties;
          ????@Bean
          ????public?static?BeanYouNeed?beanYouNeed()?{
          ?????BeanYouNeed?bean?=?new?BeanYouNeed()
          ?????bean.setField(properties.get(field));
          ?????bean.setField(properties.get(field));
          ?????bean.setField(properties.get(field));
          ????????......
          ????}
          }

          3.3.3 xxxProperties的實(shí)現(xiàn)

          這是跟配置文件相綁定的類(lèi),里邊的屬性就是我們可以在配置文件中配置的內(nèi)容,然后通過(guò)@ConfigurationProperties將其與配置文件綁定:

          @ConfigurationProperties(prefix?=?"your?properties")?//使用@ConfigurationProperties注解綁定配置文件
          public?class?xxxProperties?{

          ????private?boolean?enabled?=?true;

          ????private?String?clientId;

          ????private?String?beanName;

          ????private?String?scanBasePackage;

          ????private?String?path;

          ????private?String?token;
          }

          3.3.4 配置spring.factories文件

          在resource目錄下新建META-INF文件夾,在文件夾下新建spring.factories文件,并添加寫(xiě)好的xxxAutoConfiguration類(lèi):

          org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
          com.meituan.xframe.boot.mcc.autoconfigure.xxxAutoConfiguration

          3.4 Starter模塊開(kāi)發(fā)

          starter模塊中只進(jìn)行依賴(lài)導(dǎo)入,在pom文件中添加對(duì)autoconfigure模塊的依賴(lài),并添加一些其他必要的依賴(lài)項(xiàng):

          <dependencies>
          ?================================================================
          ?
          ?????<dependency>
          ?????????<groupId>com.test.startergroupId>
          ?????????<artifactId>xxx-spring-boot-autoconfigureartifactId>
          ?????dependency>
          ?===============================================================
          ?
          ?????<dependency>
          ?????????<groupId>commons-collectionsgroupId>
          ?????????<artifactId>commons-collectionsartifactId>
          ?????dependency>
          ?dependencies>

          這兩個(gè)模塊都開(kāi)發(fā)完成之后,通過(guò)mvn install命令或者deploy命令將包發(fā)布到本地或者中央倉(cāng)庫(kù),即可直接在其他項(xiàng)目中引用我們自定義的starter模塊了。

          推薦閱讀:

          世界的真實(shí)格局分析,地球人類(lèi)社會(huì)底層運(yùn)行原理

          不是你需要中臺(tái),而是一名合格的架構(gòu)師(附各大廠(chǎng)中臺(tái)建設(shè)PPT)

          企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案

          論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

          華為干部與人才發(fā)展手冊(cè)(附PPT)

          企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

          【中臺(tái)實(shí)踐】華為大數(shù)據(jù)中臺(tái)架構(gòu)分享.pdf

          華為的數(shù)字化轉(zhuǎn)型方法論

          華為如何實(shí)施數(shù)字化轉(zhuǎn)型(附PPT)

          超詳細(xì)280頁(yè)Docker實(shí)戰(zhàn)文檔!開(kāi)放下載

          華為大數(shù)據(jù)解決方案(PPT)


          瀏覽 54
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆国产传媒一区二区-最新 | 亚洲成人午夜影院 | 国产毛片一区 | 日韩人妻丰满无码区A片 | 天堂网2014AV |