<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
關注我Github的小夥伴應該瞭解,之前我開源了一款快速開發腳手架mall-tiny,該腳手架繼承了mall專案的技術棧,擁有完整的許可權管理功能。最近抽空把該專案支援了Spring Boot 2.7.0,今天再和大家聊聊這個腳手架,同時聊聊升級專案到Spring Boot 2.7.0的一些注意點,希望對大家有所幫助!
SpringBoot實戰電商專案mall(50k+star)地址:https://github.com/macrozheng/mall
可能有些小夥伴還不瞭解這個腳手架,我們先來聊聊它!
mall-tiny是一款基於SpringBoot+MyBatis-Plus的快速開發腳手架,目前在Github上已有1100+Star。它擁有完整的許可權管理功能,支援使用MyBatis-Plus程式碼生成器生成程式碼,可對接mall專案的Vue前端,開箱即用。
專案地址:https://github.com/macrozheng/mall-tiny
mall-tiny專案可無縫對接mall-admin-web前端專案,秒變前後端分離腳手架,由於mall-tiny專案僅實現了基礎的許可權管理功能,所以前端對接後只會展示許可權管理相關功能。
前端專案地址:https://github.com/macrozheng/mall-admin-web
這次升級不僅支援了Spring Boot 2.7.0,其他依賴版本也升級到了最新版本。
技術 | 版本 | 說明 |
---|---|---|
SpringBoot | 2.7.0 | 容器+MVC框架 |
SpringSecurity | 5.7.1 | 認證和授權框架 |
MyBatis | 3.5.9 | ORM框架 |
MyBatis-Plus | 3.5.1 | MyBatis增強工具 |
MyBatis-Plus Generator | 3.5.1 | 資料層程式碼生成器 |
Swagger-UI | 3.0.0 | 檔案生產工具 |
Redis | 5.0 | 分散式快取 |
Docker | 18.09.0 | 應用容器引擎 |
Druid | 1.2.9 | 資料庫連線池 |
Hutool | 5.8.0 | Java工具類庫 |
JWT | 0.9.1 | JWT登入支援 |
Lombok | 1.18.24 | 簡化物件封裝工具 |
化繁為簡,僅保留了許可權管理功能相關的9張表,業務簡單更加方便客製化開發,覺得mall專案學習太複雜的小夥伴可以先學習下mall-tiny。
由於升級了Swagger版本,原來的介面檔案存取路徑已經改變,最新存取路徑:http://localhost:8080/swagger-ui/
升級版本基本不影響之前的使用方式,具體使用流程可以參考最新版README檔案:
https://github.com/macrozheng/mall-tiny
接下來我們再來聊聊專案升級Spring Boot 2.7.0版本遇到的問題,這些應該是升級該版本的通用問題,你如果想升級2.7.0版本的話,瞭解下會很有幫助!
/** * Swagger API檔案相關設定 * Created by macro on 2018/4/26. */ @Configuration @EnableSwagger2 public class SwaggerConfig extends BaseSwaggerConfig { @Bean public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { return new BeanPostProcessor() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); } return bean; } private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) { List<T> copy = mappings.stream() .filter(mapping -> mapping.getPatternParser() == null) .collect(Collectors.toList()); mappings.clear(); mappings.addAll(copy); } @SuppressWarnings("unchecked") private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) { try { Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); field.setAccessible(true); return (List<RequestMappingInfoHandlerMapping>) field.get(bean); } catch (IllegalArgumentException | IllegalAccessException e) { throw new IllegalStateException(e); } } }; } }
升級Spring Boot 2.7.0版本後,原來通過繼承WebSecurityConfigurerAdapter來設定的方法已經被棄用了,僅需設定SecurityFilterChainBean即可,具體參考Spring Security最新用法。
/** * SpringSecurity 5.4.x以上新用法設定 * 為避免迴圈依賴,僅用於設定HttpSecurity * Created by macro on 2019/11/5. */ @Configuration public class SecurityConfig { @Autowired private IgnoreUrlsConfig ignoreUrlsConfig; @Autowired private RestfulAccessDeniedHandler restfulAccessDeniedHandler; @Autowired private RestAuthenticationEntryPoint restAuthenticationEntryPoint; @Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; @Autowired private DynamicSecurityService dynamicSecurityService; @Autowired private DynamicSecurityFilter dynamicSecurityFilter; @Bean SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity .authorizeRequests(); //不需要保護的資源路徑允許存取 for (String url : ignoreUrlsConfig.getUrls()) { registry.antMatchers(url).permitAll(); } //允許跨域請求的OPTIONS請求 registry.antMatchers(HttpMethod.OPTIONS) .permitAll(); // 任何請求需要身份認證 registry.and() .authorizeRequests() .anyRequest() .authenticated() // 關閉跨站請求防護及不使用session .and() .csrf() .disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 自定義許可權拒絕處理類 .and() .exceptionHandling() .accessDeniedHandler(restfulAccessDeniedHandler) .authenticationEntryPoint(restAuthenticationEntryPoint) // 自定義許可權攔截器JWT過濾器 .and() .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); //有動態許可權設定時新增動態許可權校驗過濾器 if(dynamicSecurityService!=null){ registry.and().addFilterBefore(dynamicSecurityFilter, FilterSecurityInterceptor.class); } return httpSecurity.build(); } }
MyBatis-Plus從之前的版本升級到了3.5.1版本,用法沒有大的改變,感覺最大的區別就是程式碼生成器的用法改了。 在之前的用法中我們是通過new物件然後set各種屬性來設定的,具體參考如下程式碼:
/** * MyBatisPlus程式碼生成器 * Created by macro on 2020/8/20. */ public class MyBatisPlusGenerator { /** * 初始化全域性設定 */ private static GlobalConfig initGlobalConfig(String projectPath) { GlobalConfig globalConfig = new GlobalConfig(); 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"); return globalConfig; } }
而新版的MyBatis-Plus程式碼生成器已經改成使用建造者模式來設定了,具體可以參考MyBatisPlusGenerator類中的程式碼。
/** * MyBatisPlus程式碼生成器 * Created by macro on 2020/8/20. */ public class MyBatisPlusGenerator { /** * 初始化全域性設定 */ private static GlobalConfig initGlobalConfig(String projectPath) { return new GlobalConfig.Builder() .outputDir(projectPath + "/src/main/java") .author("macro") .disableOpenDir() .enableSwagger() .fileOverride() .dateType(DateType.ONLY_DATE) .build(); } }
spring: main: allow-circular-references: true
/** * SpringSecurity 5.4.x以上新用法設定 * 為避免迴圈依賴,僅用於設定HttpSecurity * Created by macro on 2019/11/5. */ @Configuration public class SecurityConfig { @Autowired private IgnoreUrlsConfig ignoreUrlsConfig; @Autowired private RestfulAccessDeniedHandler restfulAccessDeniedHandler; @Autowired private RestAuthenticationEntryPoint restAuthenticationEntryPoint; @Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; @Autowired private DynamicSecurityService dynamicSecurityService; @Autowired private DynamicSecurityFilter dynamicSecurityFilter; @Bean SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { //省略若干程式碼... return httpSecurity.build(); } }
/** * SpringSecurity通用設定 * 包括通用Bean、Security通用Bean及動態許可權通用Bean * Created by macro on 2022/5/20. */ @Configuration public class CommonSecurityConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public IgnoreUrlsConfig ignoreUrlsConfig() { return new IgnoreUrlsConfig(); } @Bean public JwtTokenUtil jwtTokenUtil() { return new JwtTokenUtil(); } @Bean public RestfulAccessDeniedHandler restfulAccessDeniedHandler() { return new RestfulAccessDeniedHandler(); } @Bean public RestAuthenticationEntryPoint restAuthenticationEntryPoint() { return new RestAuthenticationEntryPoint(); } @Bean public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){ return new JwtAuthenticationTokenFilter(); } @Bean public DynamicAccessDecisionManager dynamicAccessDecisionManager() { return new DynamicAccessDecisionManager(); } @Bean public DynamicSecurityMetadataSource dynamicSecurityMetadataSource() { return new DynamicSecurityMetadataSource(); } @Bean public DynamicSecurityFilter dynamicSecurityFilter(){ return new DynamicSecurityFilter(); } }
/** * 後臺管理員管理Service實現類 * Created by macro on 2018/4/26. */ @Service public class UmsAdminServiceImpl extends ServiceImpl<UmsAdminMapper,UmsAdmin> implements UmsAdminService { @Autowired private UmsAdminCacheService adminCacheService; } /** * 後臺使用者快取管理Service實現類 * Created by macro on 2020/3/13. */ @Service public class UmsAdminCacheServiceImpl implements UmsAdminCacheService { @Autowired private UmsAdminService adminService; }
/** * Spring工具類 * Created by macro on 2020/3/3. */ @Component public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; // 獲取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; } } // 通過name獲取Bean public static Object getBean(String name) { return getApplicationContext().getBean(name); } // 通過class獲取Bean public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } // 通過name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
/** * 後臺管理員管理Service實現類 * Created by macro on 2018/4/26. */ @Service public class UmsAdminServiceImpl extends ServiceImpl<UmsAdminMapper,UmsAdmin> implements UmsAdminService { @Override public UmsAdminCacheService getCacheService() { return SpringUtil.getBean(UmsAdminCacheService.class); } }
在使用Spring Boot 2.7.0版本時,如果不修改之前的跨域設定,通過前端存取會出現跨域問題,後端報錯如下。
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header.
To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.
具體的意思就是allowedOrigins已經不再支援萬用字元*的設定了,改為需要使用allowedOriginPatterns來設定,具體設定修改如下。
/** * 全域性跨域設定 * Created by macro on 2019/7/27. */ @Configuration public class GlobalCorsConfig { /** * 允許跨域呼叫的過濾器 */ @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); //允許所有域名進行跨域呼叫 config.addAllowedOriginPattern("*"); //該用法在SpringBoot 2.7.0中已不再支援 //config.addAllowedOrigin("*"); //允許跨越傳送cookie config.setAllowCredentials(true); //放行全部原始頭資訊 config.addAllowedHeader("*"); //允許所有請求方法跨域呼叫 config.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
今天分享了下我的開源專案腳手架mall-tiny,以及它升級SpringBoot 2.7.0的過程。我們在寫程式碼的時候,如果有些用法已經廢棄,應該儘量去尋找新的用法來使用,這樣才能保證我們的程式碼足夠優雅!
專案地址 https://github.com/macrozheng/mall-tiny
以上就是從零搭建SpringBoot+MyBatisPlus快速開發腳手架的詳細內容,更多關於SpringBoot+MyBatisPlus從零搭建的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45