使用Springboot怎么對路徑進行掃描?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
成都創新互聯專注于企業全網整合營銷推廣、網站重做改版、渝北網站定制設計、自適應品牌網站建設、H5技術、商城網站制作、集團公司官網建設、外貿網站制作、高端網站制作、響應式網頁設計等建站業務,價格優惠性價比高,為渝北等各大城市提供網站開發制作服務。我們暫且標注下Springboot啟動過程中較為重要的邏輯方法,源碼對應的spring-boot-2.2.2.RELEASE版本
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); //@A context = createApplicationContext(); exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); //@B prepareContext(context, environment, listeners, applicationArguments, printedBanner); //@C refreshContext(context); afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } listeners.started(context); callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }
第一步:ConfigurationClassPostProcessor注入
org.springframework.context.annotation.ConfigurationClassPostProcessor是一個BeanDefinitionRegistryPostProcessor(父類是BeanFactoryPostProcessor),會在容器初始化好并裝載完第一階段的bean定義后調用,我理解的其主要作用是執行一些框架內部方法也讓用戶自定義再次注入自定義的bean定義;
它的注冊是在SpringApplication.run方法調用后,具體調用鏈是
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...) ->org.springframework.boot.SpringApplication#run(java.lang.String...) ->org.springframework.boot.SpringApplication#createApplicationContext //對應上面@A標注的地方 //后續會初始化一個org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext對象,在構造方法里會執行一系列的邏輯 ->org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry) ->org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.core.env.Environment) ->org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry) ->org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object) //這個方法會注入5個bean定義: 1. ConfigurationClassPostProcessor.class 2. AutowiredAnnotationBeanPostProcessor.class 3. CommonAnnotationBeanPostProcessor.class 4. EventListenerMethodProcessor.class 5. DefaultEventListenerFactory.class
第二步:啟動類bean定義注入
被我們標記了@SpringBootApplication的類在運行過程中會被包裝成一個bean定義,放入容器中;具體方法調用鏈
org.springframework.boot.SpringApplication#run(java.lang.String...) org.springframework.boot.SpringApplication#prepareContext //對應上面代碼標注 @B 的地方 org.springframework.boot.SpringApplication#load org.springframework.boot.BeanDefinitionLoader#load(java.lang.Object) org.springframework.boot.BeanDefinitionLoader#load(java.lang.Class<?>) org.springframework.context.annotation.AnnotatedBeanDefinitionReader#register org.springframework.context.annotation.AnnotatedBeanDefinitionReader#registerBean(java.lang.Class<?>) org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean //里面一段代碼 如下: AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); //從這個方法里可以看出,啟動類被包裝成了 AnnotatedGenericBeanDefinition(實現了AnnotatedBeanDefinition接口,這很重要)
第三步:解析包掃描信息并完成剩余bean注冊
剛剛在第一步里,容器中注入了ConfigurationClassPostProcessor后置處理器,后置處理器會在核心方法refresh中執行,也就是上面標注@C的代碼里;
我們直接來到核心邏輯處,調用鏈:
由于第二步容器中將啟動類包裝成AnnotatedGenericBeanDefinition并注入了容器,在方法
org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)會被處理執行后續的包掃描
看完上述內容,你們掌握使用Springboot怎么對路徑進行掃描的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!
網站欄目:使用Springboot怎么對路徑進行掃描-創新互聯
URL鏈接:http://vcdvsql.cn/article16/ccspgg.html
成都網站建設公司_創新互聯,為您提供網站維護、服務器托管、移動網站建設、做網站、小程序開發、網站設計公司
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯