SpringBoot自動配置原理及案例源碼解析
一、什么是SpringBoot自動配置
首先介紹一下什么是SpringBoot,SpringBoost是基于Spring框架開發(fā)出來的功能更強大的Java程序開發(fā)框架,其最主要的特點是:能使程序開發(fā)者快速搭建一套開發(fā)環(huán)境。SpringBoot 能將主流的開發(fā)框架(例如SpringMVC,Dubbo,Mybatis,Redis等),做到像Maven導(dǎo)入Jar包一樣的簡潔快速,做到開箱即用。其中最關(guān)鍵的技術(shù)就是 SpringBoot定制的各種Starter,通Maven引入Starter就能快速搭建開發(fā)環(huán)境。
二、SpringBoot Starter自動裝配案例
在以前單獨使用SpringMVC Web編程框架時,我們需要單獨配置DispatcherServlet和Tomcat,使用SpringBoot之后,我們只需要引入SpringBoot-Starter-Web就能直接開始編寫Controller等Web相關(guān)的代碼,這就是SpringBoot為們提供的開箱即用的便捷能力,下面就以SpringBoot-Starter-Web 來說明SpringBoot自動配置的關(guān)鍵原理
三、SpringBoot自動裝配案例源碼解析
3.1 DispatcherServlet的自動配置原理
首先我們定位到SpringBoot自動配置的Maven依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>${spring-boot.version}</version> </dependency>
在依賴的Jar包中我們可以在META-INF/spring.factories中找到自動配置類:
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration.DispatcherServletConfiguration
下圖是這個配置類的主要源碼和解析:
下面將上圖中關(guān)鍵的注解功能,分別進行功能說明
3.1.1:@EnableConfigurationProperties ({WebMvcProperties.class}) 注解解析
這個注解表示使WebMvcProperties.class類上的@ConfigurationProperties這個注解生效,同時@ConfigurationProperties這個注解是將application.xml中以 spring.mvc開頭的配置參數(shù)自動注入到WebMvcProperties.class類的字段中
3.1.2:@Conditional ({DefaultDispatcherServletCondition.class} 注解解析
該注解的原理就是將滿足特定條件情況下的Bean自動加載到Spring容器中,該注解對應(yīng)的Spring接口就是 rg.springframework.context.annotation.Condition這個接口
public interface Condition { boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2); }
3.1.3:@ConditionOnClass注解解析
@ConditionOnClass這個注解是在當(dāng)程序代碼環(huán)境classpath下存在xxx.class的情況下條件成立,同時最終也會調(diào)用到matches方法中,其中關(guān)鍵的源碼如下:
protected static Class<?> resolve(String className, ClassLoader classLoader) throws ClassNotFoundException { return classLoader != null ? Class.forName(className, false, classLoader) : Class.forName(className); }
從上面可以看到,代碼利用Class.forName方法加載classpath下的xxx.class類,如果加載成功條件就會成立。最后,在滿足了所有@ConditionOnal注解條件后,SpringBoot就會自動為我們在Spring容器中注入DispatcherServlet了,無需單獨配置了,直接引入pring-boot-starter-webr即可開始使用web相關(guān)功能。
3.1.4:小結(jié)
我們以DispatcherServlet是如何自動配置到容器中為例,探究了SpringBoot Starter的自動配置原理,其中涉及了幾個關(guān)鍵的注解和步驟:
第一步:涉及到了配置文件的讀取和個性化配置,這里就涉及到了下面這兩個注解
@ConfigurationProperties @EnableConfigurationProperties
第二步:設(shè)計到了在什么條件下才自動配置的注解
@Conditional @ConditionalOnClass
第三步:約定了自動配置類的加載路徑
/META-INF/spring-factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=自動配置類全路徑名稱
在我們了解到了SpringBoot自動配置的原理之后,我們就可以自定義一個SpringBoot Starter來快速搭建我們的開發(fā)環(huán)境了。
四、自定義一個打印輸入輸出日志的Starter
4.1 首先定義一個標(biāo)記需要打印出入?yún)⑷罩镜淖⒔釦PrintLog
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PrintLog { }
4.2 定義一個存放打印日志配置的實體類
//自動注入application配置文件中已log.switch開頭的配置參數(shù) @ConfigurationProperties("log.switch") public class LogProperties { //是否啟用打印日志功能 private Boolean enabled = false; //是否打印調(diào)用者ip private Boolean printIp = false; //是否打印調(diào)用者url private Boolean printUrl = false }
4.3 定義一個@PrintLog注解的切面類
@Aspect public class LogAspect { private static final Log LOGGER = LogFactory.getLog(LogAspect.class); private LogProperties logProperties; @Pointcut("@annotation(com.zl.annotation.PrintLog)") public void Log(){} @Around("Log()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); String methodName = method.getName(); //打印調(diào)用url if (Boolean.TRUE.equals(logProperties.getPrintUrl())){ LOGGER.info("URL:" + request.getRequestURL().toString()); } //打印ip if (Boolean.TRUE.equals(logProperties.getPrintIp())) { LOGGER.info("IP :" + request.getRemoteAddr()); } //打印方法 LOGGER.info("method :" + methodName); //打印參數(shù) LOGGER.info("parameter :" + Arrays.toString(joinPoint.getArgs())); Object result = joinPoint.proceed(); //打印返回結(jié)果 LOGGER.info("return :" + JSON.toJSONString(result)); return result; } }
4.4 定義一個打印日志的自動配置類
@Configuration @EnableConfigurationProperties({LogProperties.class}) //表示在application配置文件中必須配置log.switch.enabled = true才啟動自動配置 @ConditionalOnProperty(prefix = "log.switch", value = "enabled", havingValue = "true") public class LogAutoConfigure { @Bean //Advice.class是aop切面中關(guān)鍵的切面方法類(@Before,@After等) //程序中有Advice.class類說明需要使用切面功能,這時才加載自定義的切面類 @ConditionalOnClass(Advice.class) public LogAspect webLogAspect(LogProperties logProperties){ return new LogAspect(logProperties); } }
總結(jié)
SpringBoot自動配置功能帶給我們的是開箱即用,快速便捷的功能,自動配置為我們研發(fā)人員帶來的優(yōu)點,我主要總結(jié)為以下兩點:
- 提高研發(fā)效率 。我們可以快速構(gòu)建開發(fā)環(huán)境,對于開發(fā)中使用到的開源組件和中間件,我們直接引入對應(yīng)的Starter就可以直接開發(fā)了,例如Redis和Mybati等,可以直接引入對應(yīng)的spring-boot-starter-data-redis就可以直接使用RedisTemplate來操作 Redis了,這樣可以極大的提高研發(fā)的效率,無需再進行復(fù)雜的起步配置了和各種版本依賴管理了。
- 標(biāo)準(zhǔn)模塊復(fù)用。對于業(yè)務(wù)開發(fā)中的一些標(biāo)準(zhǔn)模塊,例如常用的一些三方服務(wù),我們可以利用Starter直接配置好,在需要使用的項目中直接引入這個starter就可以立即使用了,無需再去引入Jar包和編寫配置文件等,同樣的,對于一些標(biāo)準(zhǔn)非業(yè)務(wù)強耦合的功能,例如監(jiān)控,鑒權(quán)等,也可以定義一個Starter,需要使用鑒權(quán)和監(jiān)控功能的項目就可以直接復(fù)用了,無需再次開發(fā)。
以上就是SpringBoot自動配置原理及案例源碼解析的詳細內(nèi)容,更多關(guān)于SpringBoot自動配置的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot啟動時運行特定代碼的多種方式小結(jié)
SpringBoot提供了多種方式在應(yīng)用程序啟動時運行特定的代碼,包括CommandLineRunner、ApplicationRunner、@PostConstruct、InitializingBean、事件機制和自定義注解等,下面就來具體介紹一下2025-01-01Java中生成不重復(fù)隨機數(shù)的四種方法舉例詳解
在Java編程中獲取隨機數(shù)是常見的需求,這篇文章主要介紹了Java中生成不重復(fù)隨機數(shù)的四種方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-04-04FeignClientFactoryBean創(chuàng)建動態(tài)代理詳細解讀
這篇文章主要介紹了FeignClientFactoryBean創(chuàng)建動態(tài)代理詳細解讀,當(dāng)直接進去注冊的方法中,一步步放下走,都是直接放bean的定義信息中放入值,然后轉(zhuǎn)成BeanDefinitionHolder,最后在注冊到IOC容器中,需要的朋友可以參考下2023-11-11解決Spring?Security升級到5.5.7、5.6.4及以上啟動報錯出現(xiàn)版本不兼容的問題
這篇文章主要介紹了解決Spring?Security升級到5.5.7、5.6.4及以上啟動報錯出現(xiàn)版本不兼容的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08SpringBoot前后端分離跨域問題:狀態(tài)碼403拒絕訪問解決辦法
這篇文章主要給大家介紹了關(guān)于SpringBoot前后端分離跨域問題:狀態(tài)碼403拒絕訪問的解決辦法,403是被服務(wù)器拒絕了,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-01-01JavaWeb使用Session和Cookie實現(xiàn)登錄認證
本篇文章主要介紹了JavaWeb使用Session和Cookie實現(xiàn)登錄認證,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03