從零搭建SpringBoot+MyBatisPlus快速開發(fā)腳手架_第1頁
從零搭建SpringBoot+MyBatisPlus快速開發(fā)腳手架_第2頁
從零搭建SpringBoot+MyBatisPlus快速開發(fā)腳手架_第3頁
從零搭建SpringBoot+MyBatisPlus快速開發(fā)腳手架_第4頁
從零搭建SpringBoot+MyBatisPlus快速開發(fā)腳手架_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第從零搭建SpringBoot+MyBatisPlus快速開發(fā)腳手架目錄前言聊聊mall-tiny項目項目簡介項目演示技術(shù)選型數(shù)據(jù)庫表結(jié)構(gòu)接口文檔使用流程升級過程Swagger升級SpringSecurity升級MyBatis-Plus升級解決循環(huán)依賴問題解決跨域問題總結(jié)

前言

關(guān)注我Github的小伙伴應(yīng)該了解,之前我開源了一款快速開發(fā)腳手架mall-tiny,該腳手架繼承了mall項目的技術(shù)棧,擁有完整的權(quán)限管理功能。最近抽空把該項目支持了SpringBoot2.7.0,今天再和大家聊聊這個腳手架,同時聊聊升級項目到SpringBoot2.7.0的一些注意點,希望對大家有所幫助!

SpringBoot實戰(zhàn)電商項目mall(50k+star)地址:/macrozheng/mall

聊聊mall-tiny項目

可能有些小伙伴還不了解這個腳手架,我們先來聊聊它!

項目簡介

mall-tiny是一款基于SpringBoot+MyBatis-Plus的快速開發(fā)腳手架,目前在Github上已有1100+Star。它擁有完整的權(quán)限管理功能,支持使用MyBatis-Plus代碼生成器生成代碼,可對接mall項目的Vue前端,開箱即用。

項目地址:/macrozheng/mall-tiny

項目演示

mall-tiny項目可無縫對接mall-admin-web前端項目,秒變前后端分離腳手架,由于mall-tiny項目僅實現(xiàn)了基礎(chǔ)的權(quán)限管理功能,所以前端對接后只會展示權(quán)限管理相關(guān)功能。

前端項目地址:/macrozheng/mall-admin-web

技術(shù)選型

這次升級不僅支持了SpringBoot2.7.0,其他依賴版本也升級到了最新版本。

技術(shù)版本說明SpringBoot2.7.0容器+MVC框架SpringSecurity5.7.1認證和授權(quán)框架MyBatis3.5.9ORM框架MyBatis-Plus3.5.1MyBatis增強工具MyBatis-PlusGenerator3.5.1數(shù)據(jù)層代碼生成器Swagger-UI3.0.0文檔生產(chǎn)工具Redis5.0分布式緩存Docker18.09.0應(yīng)用容器引擎Druid1.2.9數(shù)據(jù)庫連接池Hutool5.8.0Java工具類庫JWT0.9.1JWT登錄支持Lombok1.18.24簡化對象封裝工具

數(shù)據(jù)庫表結(jié)構(gòu)

化繁為簡,僅保留了權(quán)限管理功能相關(guān)的9張表,業(yè)務(wù)簡單更加方便定制開發(fā),覺得mall項目學(xué)習(xí)太復(fù)雜的小伙伴可以先學(xué)習(xí)下mall-tiny。

接口文檔

由于升級了Swagger版本,原來的接口文檔訪問路徑已經(jīng)改變,最新訪問路徑:http://localhost:8080/swagger-ui/

使用流程

升級版本基本不影響之前的使用方式,具體使用流程可以參考最新版README文件:

/macrozheng/mall-tiny

升級過程

接下來我們再來聊聊項目升級SpringBoot2.7.0版本遇到的問題,這些應(yīng)該是升級該版本的通用問題,你如果想升級2.7.0版本的話,了解下會很有幫助!

Swagger升級

在升級SpringBoot2.6.x版本的時候,其實Swagger就有一定的兼容性問題,需要在配置中添加BeanPostProcessor這個Bean,具體可以參考升級SpringBoot2.6.x版本后,Swagger沒法用了!;

/**

*SwaggerAPI文檔相關(guān)配置

*Createdbymacroon2025/4/26.

@Configuration

@EnableSwagger2

publicclassSwaggerConfigextendsBaseSwaggerConfig{

@Bean

publicstaticBeanPostProcessorspringfoxHandlerProviderBeanPostProcessor(){

returnnewBeanPostProcessor(){

@Override

publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{

if(beaninstanceofWebMvcRequestHandlerProvider||beaninstanceofWebFluxRequestHandlerProvider){

customizeSpringfoxHandlerMappings(getHandlerMappings(bean));

returnbean;

privateTextendsRequestMappingInfoHandlerMappingvoidcustomizeSpringfoxHandlerMappings(ListTmappings){

ListTcopy=mappings.stream()

.filter(mapping-mapping.getPatternParser()==null)

.collect(Collectors.toList());

mappings.clear();

mappings.addAll(copy);

@SuppressWarnings("unchecked")

privateListRequestMappingInfoHandlerMappinggetHandlerMappings(Objectbean){

try{

Fieldfield=ReflectionUtils.findField(bean.getClass(),"handlerMappings");

field.setAccessible(true);

return(ListRequestMappingInfoHandlerMapping)field.get(bean);

}catch(IllegalArgumentException|IllegalAccessExceptione){

thrownewIllegalStateException(e);

之前我們通過@Api注解的description屬性來配置接口描述的方法已經(jīng)被棄用了;

我們可以使用@Tag注解來配置接口說明,并使用@Api注解中的tags屬性來指定。

SpringSecurity升級

升級SpringBoot2.7.0版本后,原來通過繼承WebSecurityConfigurerAdapter來配置的方法已經(jīng)被棄用了,僅需配置SecurityFilterChainBean即可,具體參考SpringSecurity最新用法。

/**

*SpringSecurity5.4.x以上新用法配置

*為避免循環(huán)依賴,僅用于配置HttpSecurity

*Createdbymacroon2025/11/5.

@Configuration

publicclassSecurityConfig{

@Autowired

privateIgnoreUrlsConfigignoreUrlsConfig;

@Autowired

privateRestfulAccessDeniedHandlerrestfulAccessDeniedHandler;

@Autowired

privateRestAuthenticationEntryPointrestAuthenticationEntryPoint;

@Autowired

privateJwtAuthenticationTokenFilterjwtAuthenticationTokenFilter;

@Autowired

privateDynamicSecurityServicedynamicSecurityService;

@Autowired

privateDynamicSecurityFilterdynamicSecurityFilter;

@Bean

SecurityFilterChainfilterChain(HttpSecurityhttpSecurity)throwsException{

ExpressionUrlAuthorizationConfigurerHttpSecurity.ExpressionInterceptUrlRegistryregistry=httpSecurity

.authorizeRequests();

//不需要保護的資源路徑允許訪問

for(Stringurl:ignoreUrlsConfig.getUrls()){

registry.antMatchers(url).permitAll();

//允許跨域請求的OPTIONS請求

registry.antMatchers(HttpMethod.OPTIONS)

.permitAll();

//任何請求需要身份認證

registry.and()

.authorizeRequests()

.anyRequest()

.authenticated()

//關(guān)閉跨站請求防護及不使用session

.and()

.csrf()

.disable()

.sessionManagement()

.sessionCreationPolicy(SessionCreationPolicy.STATELESS)

//自定義權(quán)限拒絕處理類

.and()

.exceptionHandling()

.accessDeniedHandler(restfulAccessDeniedHandler)

.authenticationEntryPoint(restAuthenticationEntryPoint)

//自定義權(quán)限攔截器JWT過濾器

.and()

.addFilterBefore(jwtAuthenticationTokenFilter,UsernamePasswordAuthenticationFilter.class);

//有動態(tài)權(quán)限配置時添加動態(tài)權(quán)限校驗過濾器

if(dynamicSecurityService!=null){

registry.and().addFilterBefore(dynamicSecurityFilter,FilterSecurityInterceptor.class);

returnhttpSecurity.build();

MyBatis-Plus升級

MyBatis-Plus從之前的版本升級到了3.5.1版本,用法沒有大的改變,感覺最大的區(qū)別就是代碼生成器的用法改了。在之前的用法中我們是通過new對象然后set各種屬性來配置的,具體參考如下代碼:

/**

*MyBatisPlus代碼生成器

*Createdbymacroon2025/8/20.

publicclassMyBatisPlusGenerator{

*初始化全局配置

privatestaticGlobalConfiginitGlobalConfig(StringprojectPath){

GlobalConfigglobalConfig=newGlobalConfig();

globalConfig.setOutputDir(projectPath+"/src/main/java");

globalConfig.setAuthor("macro");

globalConfig.setOpen(false);

globalConfig.setSwagger2(true);

globalConfig.setBaseResultMap(true);

globalConfig.setFileOverride(true);

globalConfig.setDateType(DateType.ONLY_DATE);

globalConfig.setEntityName("%s");

globalConfig.setMapperName("%sMapper");

globalConfig.setXmlName("%sMapper");

globalConfig.setServiceName("%sService");

globalConfig.setServiceImplName("%sServiceImpl");

globalConfig.setControllerName("%sController");

returnglobalConfig;

而新版的MyBatis-Plus代碼生成器已經(jīng)改成使用建造者模式來配置了,具體可以參考MyBatisPlusGenerator類中的代碼。

/**

*MyBatisPlus代碼生成器

*Createdbymacroon2025/8/20.

publicclassMyBatisPlusGenerator{

*初始化全局配置

privatestaticGlobalConfiginitGlobalConfig(StringprojectPath){

returnnewGlobalConfig.Builder()

.outputDir(projectPath+"/src/main/java")

.author("macro")

.disableOpenDir()

.enableSwagger()

.fileOverride()

.dateType(DateType.ONLY_DATE)

.build();

解決循環(huán)依賴問題

其實SpringBoot從2.6.x版本已經(jīng)開始不推薦使用循環(huán)依賴了,如果你的項目中使用的循環(huán)依賴比較多的話,可以使用如下配置開啟;

spring:

main:

allow-circular-references:true

不過既然官方都不推薦使用了,我們最好還是避免循環(huán)依賴的好,這里分享下我解決循環(huán)依賴問題的一點思路。如果一個類里有多個依賴項,這個類非必要的Bean就不要配置了,可以使用單獨的類來配置Bean。比如SecurityConfig這個配置類中,我只聲明了必要的SecurityFilterChain配置;

/**

*SpringSecurity5.4.x以上新用法配置

*為避免循環(huán)依賴,僅用于配置HttpSecurity

*Createdbymacroon2025/11/5.

@Configuration

publicclassSecurityConfig{

@Autowired

privateIgnoreUrlsConfigignoreUrlsConfig;

@Autowired

privateRestfulAccessDeniedHandlerrestfulAccessDeniedHandler;

@Autowired

privateRestAuthenticationEntryPointrestAuthenticationEntryPoint;

@Autowired

privateJwtAuthenticationTokenFilterjwtAuthenticationTokenFilter;

@Autowired

privateDynamicSecurityServicedynamicSecurityService;

@Autowired

privateDynamicSecurityFilterdynamicSecurityFilter;

@Bean

SecurityFilterChainfilterChain(HttpSecurityhttpSecurity)throwsException{

//省略若干代碼...

returnhttpSecurity.build();

其他配置都被我移動到了CommonSecurityConfig配置類中,這樣就避免了之前的循環(huán)依賴;

/**

*SpringSecurity通用配置

*包括通用Bean、Security通用Bean及動態(tài)權(quán)限通用Bean

*Createdbymacroon2025/5/20.

@Configuration

publicclassCommonSecurityConfig{

@Bean

publicPasswordEncoderpasswordEncoder(){

returnnewBCryptPasswordEncoder();

@Bean

publicIgnoreUrlsConfigignoreUrlsConfig(){

returnnewIgnoreUrlsConfig();

@Bean

publicJwtTokenUtiljwtTokenUtil(){

returnnewJwtTokenUtil();

@Bean

publicRestfulAccessDeniedHandlerrestfulAccessDeniedHandler(){

returnnewRestfulAccessDeniedHandler();

@Bean

publicRestAuthenticationEntryPointrestAuthenticationEntryPoint(){

returnnewRestAuthenticationEntryPoint();

@Bean

publicJwtAuthenticationTokenFilterjwtAuthenticationTokenFilter(){

returnnewJwtAuthenticationTokenFilter();

@Bean

publicDynamicAccessDecisionManagerdynamicAccessDecisionManager(){

returnnewDynamicAccessDecisionManager();

@Bean

publicDynamicSecurityMetadataSourcedynamicSecurityMetadataSource(){

returnnewDynamicSecurityMetadataSource();

@Bean

publicDynamicSecurityFilterdynamicSecurityFilter(){

returnnewDynamicSecurityFilter();

還有一個典型的循環(huán)依賴問題,UmsAdminServiceImpl和UmsAdminCacheServiceImpl相互依賴了;

/**

*后臺管理員管理Service實現(xiàn)類

*Createdbymacroon2025/4/26.

@Service

publicclassUmsAdminServiceImplextendsServiceImplUmsAdminMapper,UmsAdminimplementsUmsAdminService{

@Autowired

privateUmsAdminCacheServiceadminCacheService;

*后臺用戶緩存管理Service實現(xiàn)類

*Createdbymacroon2025/3/13.

@Service

publicclassUmsAdminCacheServiceImplimplementsUmsAdminCacheService{

@Autowired

privateUmsAdminServiceadminService;

我們可以創(chuàng)建一個用于獲取Spring容器中的Bean的工具類來實現(xiàn);

/**

*Spring工具類

*Createdbymacroon2025/3/3.

@Component

publicclassSpringUtilimplementsApplicationContextAware{

privatestaticApplicationContextapplicationContext;

//獲取applicationContext

publicstaticApplicationContextgetApplicationContext(){

returnapplicationContext;

@Override

publicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{

if(SpringUtil.applicationContext==null){

SpringUtil.applicationContext=applicationContext;

//通過name獲取Bean

publicstaticObjectgetBean(Stringname){

returngetApplicationContext().getBean(name);

//通過class獲取Bean

publicstaticTTgetBean(ClassTclazz){

returngetApplicationContext().getBean(clazz);

//通過name,以及Clazz返回指定的Bean

publicstaticTTgetBean(Stringname,ClassTclazz){

returngetApplicationContext().getBean(name,clazz);

然后在UmsAdminServiceImpl中使用該工具類獲取Bean來解決循環(huán)依賴。

/**

*后臺管理員管理Service實現(xiàn)類

*Createdbymacroon2025/4/26.

@Service

publicclassUmsAdminServiceImplextendsServiceImplUmsAdminMapper,UmsAdminimplementsUmsAdminService{

@Override

publicUmsAdminCacheServicegetCacheService(){

returnSpringUtil.getBean(UmsAdminCacheService.class);

解決跨域問題

在使用SpringBoot2.7.0版本時,如果不修改之前的跨域配置,通過前端訪問會出現(xiàn)跨域問題,后端報錯如下。

java.lang.IllegalArgumentException:WhenallowCredentialsistrue,allowedOriginscannotcontainthespecialvalue*sincethatca

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論