Einige Freunde verstehen dieses Gerüst vielleicht noch nicht, lass uns zuerst darüber reden!
mall-tiny ist ein schnelles Entwicklungsgerüst basierend auf SpringBoot+MyBatis-Plus. Es hat derzeit 1100+Sterne auf Github. Es verfügt über vollständige Berechtigungsverwaltungsfunktionen, unterstützt die Verwendung des MyBatis-Plus-Codegenerators zum Generieren von Code und kann mit dem Vue-Frontend des Einkaufszentrumprojekts verbunden werden, sodass es sofort einsatzbereit ist.
Das Mall-Tiny-Projekt kann nahtlos mit dem Mall-Admin-Web-Frontend-Projekt verbunden werden, und das Front-End- und Back-End-Trenngerüst kann in Sekundenschnelle umgestaltet werden Das -tiny-Projekt implementiert nur grundlegende Berechtigungsverwaltungsfunktionen. Nach dem Front-End-Andocken werden nur Funktionen im Zusammenhang mit der Berechtigungsverwaltung angezeigt.
Dieses Upgrade unterstützt nicht nur Spring Boot 2.7.0, sondern auch andere abhängige Versionen wurden auf die neuesten Versionen aktualisiert.
Technologie | Version | Beschreibung |
---|---|---|
SpringBoot | 2.7.0 | Container+MVC Framework |
SpringSecurity | 5. 7.1 | Authentifizierungs- und Autorisierungs-Framework |
MyBatis | 3.5.9. ORM-Framework.Swagger – UI | |
Dokumentenproduktionstool | Redis | |
Verteilter Cache | Docker | |
Application Container Engine | Druide | |
Datenbankverbindungspool | Hutool | |
Java-Toolbibliothek | JWT | |
JWT-Anmeldeunterstützung | Lombok | |
Verpackungswerkzeuge für Objekte vereinfachen |
数据库表结构化繁为简,仅保留了权限管理功能相关的9张表,业务简单更加方便定制开发,觉得mall项目学习太复杂的小伙伴可以先学习下mall-tiny。 接口文档由于升级了Swagger版本,原来的接口文档访问路径已经改变,最新访问路径:http://localhost:8080/swagger-ui/ 使用流程升级版本基本不影响之前的使用方式,具体使用流程可以参考最新版README文件: 升级过程接下来我们再来聊聊项目升级Spring Boot 2.7.0版本遇到的问题,这些应该是升级该版本的通用问题,你如果想升级2.7.0版本的话,了解下会很有帮助! Swagger升级
/** * 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); } } }; } } Nach dem Login kopieren
Spring Security升级升级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(); } } Nach dem Login kopieren MyBatis-Plus升级MyBatis-Plus从之前的版本升级到了3.5.1版本,用法没有大的改变,感觉最大的区别就是代码生成器的用法改了。以前我们使用的方法是创建一个新对象,然后通过设置各种属性来进行配置,具体例子请参考以下代码: /** * 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; } } Nach dem Login kopieren 而新版的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(); } } Nach dem Login kopieren 解决循环依赖问题
spring: main: allow-circular-references: true Nach dem Login kopieren
/** * 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(); } } Nach dem Login kopieren
/** * 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(); } } Nach dem Login kopieren
/** * 后台管理员管理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; } Nach dem Login kopieren
/** * 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); } } Nach dem Login kopieren
/** * 后台管理员管理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); } } Nach dem Login kopieren 解决跨域问题在使用Spring Boot 2.7.0版本时,如果不修改之前的跨域配置,通过前端访问会出现跨域问题,后端报错如下。
具体的意思就是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); } } Nach dem Login kopieren |
Das obige ist der detaillierte Inhalt vonSo erstellen Sie ein SpringBoot+MyBatisPlus-Schnellentwicklungsgerüst. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!