springboot启动类
提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 前言
- 一、簡單回顧
- 二、run方法的入?yún)?/li>
- 三、ComponentScan的掃描范圍
- 總結(jié)
前言
提示:這里可以添加本文要記錄的大概內(nèi)容:
springboot啟動流程有很多文章都介紹得很詳細(xì)了,今天我們換種方式來討論下啟動類。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、簡單回顧
1、首先快速創(chuàng)建一個springboot項目,編寫一個測試接口。
@RestController public class UserController {@RequestMapping("/test")public String getNameById(String id){System.out.println("測試接口入?yún)?#xff0c;id="+id);return "lili";} }
接口正常,這是我們按默認(rèn)方式創(chuàng)建項目。我們的啟動類也很簡單就是默認(rèn)創(chuàng)建的。
2、下面我們來改造下啟動類,demo1:將啟動類的注解去掉,run方法入?yún)Q一個配置類
import com.jy.demo.config.AopConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;//@SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(AopConfig.class, args);} } import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.*;/*** @Author jy* @Date 2022/4/2 15:38* @Version 1.0*/ @Configuration @ComponentScan(basePackages = "com.jy.demo.controller") //@EnableAspectJAutoProxy @EnableAutoConfiguration //@Import(JyAfterFilter.class) public class AopConfig {}啟動服務(wù)測試接口,發(fā)現(xiàn)服務(wù)正常啟動,接口調(diào)用也是正常
從目前來看這樣操作是沒有問題。那么我們再來試試demo2的方式修改,先新建兩個類具體位置如圖
從圖片中可以看出,main所在的類在app包下,配置類在最外層,這時我用TestApplication啟動,服務(wù)也是正常運行,測試接口也是正常調(diào)用成功
3、我們再修改下代碼,demo3:配置類也改一下
服務(wù)啟動依然正常,接口測試也正常
我們幾種修改都能正常啟動,接口也正常調(diào)用,那么為什么可以呢?
二、run方法的入?yún)?/h1>
1、首先我們還是回顧下spring的注解模式
public class Demo9 {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);applicationContext.publishEvent(new ApplicationEvent("監(jiān)聽事件推送") {});Apple bean = applicationContext.getBean(Apple.class);bean.setId(1);System.out.println(bean);} } public void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register").tag("classes", () -> Arrays.toString(componentClasses));this.reader.register(componentClasses);//注意這行代碼!!!!registerComponentClass.end();}傳入的參數(shù)就是一個配置類,spring先將這個配置類注入容器,然后在BeanFactoryPostProccsor的實現(xiàn)中處理配置類帶來的該處理的對象。具體的操作可以看看Configuration注解解析,而springboot的啟動類中的run方法入?yún)⑹鞘裁茨?#xff1f;其實也是一個配置類,那么springboot是怎么用這個配置類的呢?
首先是將這個配置類放在SpringApplication的成員變量里,然后在run方法中的上下文應(yīng)用準(zhǔn)備的時候?qū)ε渲妙愡M(jìn)行了處理。
往下一步就是在load()方法中加載
這里因為我們看的配置類,所以進(jìn)入第一個if中,再往里走就到了我們前面spring處理時的類似代碼了
圈上的這行代碼和前面提示注意的那行代碼就是一個意思了,到目前為止說清楚了,這個配置類被注冊到容器的過程,那么和我們啟動類的位置有什么關(guān)系呢?
三、ComponentScan的掃描范圍
細(xì)心的朋友可能已經(jīng)發(fā)現(xiàn),我們幾次修改的時候配置類的ComponentScan的value值是有所不同的,@SpringBootApplication的value值是默認(rèn)空,而自己寫的配置類上的ComponentScan注解是加了路徑值的。兩者的區(qū)別在于,默認(rèn)空的話,掃描路徑是按配置類所在的位置掃描同級及下級;有值的話就按填寫的值進(jìn)行掃描同級及下級。這個操作在ConfigurationClassPostProcessor類處理配置類信息時處理的。而配置類的信息在前面已經(jīng)說了是怎么注冊到容器中的,所以spring能處理到我們的啟動配置類,也順其自然的能處理到配置類上的掃描范圍。所以雖然我們修改了main方法文件所在的位置,修改了配置類的位置服務(wù)依然能正常啟用,接口也正常調(diào)用。
總結(jié)
唉,前面屁話了一堆,第三點就這么點東西說明了原因。最后再多一嘴,
既然啟動類的位置可以不在最外層,那springboot為什么要放在最外層呢?因為springboot不知道我們會寫些什么包路徑,所以放最外層從最外層往下掃描,將對象是否注入容器交給開發(fā)者(需要注入就加注解)。以上就是我的一點個人理解,歡迎大家斧正。大家一起加油!!!
總結(jié)
以上是生活随笔為你收集整理的springboot启动类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷P3369 AVL树
- 下一篇: 网页版飞信(Fetion)的安全问题