当前位置:网站首页>Still building projects from scratch? This upgraded rapid development scaffold is worth a try!
Still building projects from scratch? This upgraded rapid development scaffold is worth a try!
2022-07-24 17:50:00 【macrozheng】
Pay attention to me Github My little friend should know , Before I open source a rapid development scaffold
mall-tiny, This scaffold inherits mall The technical stack of the project , It has complete authority management function . Recently, I took the time to support the projectSpring Boot 2.7.0, Today, I will talk about this scaffold , At the same time, talk about upgrading the project toSpring Boot 2.7.0Some points for attention , I hope that's helpful !
Chat mall-tiny project
Maybe some little friends don't know about this scaffold , Let's talk about it first !
Project brief introduction
mall-tiny It's based on SpringBoot+MyBatis-Plus The rapid development of scaffolding , Currently in Github Previous 1100+Star. It has complete rights management functions , Support use MyBatis-Plus Code generator generates code , It can be docked mall Project Vue front end , Open the box .
Project address :https://github.com/macrozheng/mall-tiny
Project presentations
mall-tiny Projects can be seamlessly connected mall-admin-web The front-end project , Second change front and rear end separation scaffold , because mall-tiny The project only implements the basic permission management function , Therefore, after the front-end is connected, only the functions related to permission management will be displayed .
Front end project address :https://github.com/macrozheng/mall-admin-web
Technology selection
This upgrade not only supports Spring Boot 2.7.0, Other dependent versions have also been upgraded to the latest version .
technology | edition | explain |
|---|---|---|
SpringBoot | 2.7.0 | Containers +MVC frame |
SpringSecurity | 5.7.1 | Certification and authorization framework |
MyBatis | 3.5.9 | ORM frame |
MyBatis-Plus | 3.5.1 | MyBatis Enhancement tool |
MyBatis-Plus Generator | 3.5.1 | Data layer code generator |
Swagger-UI | 3.0.0 | Document production tools |
Redis | 5.0 | Distributed cache |
Docker | 18.09.0 | Application container engine |
Druid | 1.2.9 | Database connection pool |
Hutool | 5.8.0 | Java Tool library |
JWT | 0.9.1 | JWT Login support |
Lombok | 1.18.24 | Simplified object encapsulation tool |
Database table structure
Change numerous for brief , Only those related to the rights management function are reserved 9 A watch , Simple business, more convenient for customized development , Think mall If the project learning is too complicated, you can learn first mall-tiny.
Interface document
Due to the upgrade Swagger edition , The original interface document access path has been changed , Latest access path :http://localhost:8080/swagger-ui/
Usage flow
The upgraded version basically does not affect the previous usage , Please refer to the latest version for the specific use process README file :https://github.com/macrozheng/mall-tiny
Upgrade process
Next, let's talk about project upgrading Spring Boot 2.7.0 Version problems , These should be general issues for upgrading this version , If you want to upgrade 2.7.0 Version! , It would be helpful to know !
Swagger upgrade
- The upgrade Spring Boot 2.6.x At version time , Actually Swagger There are certain compatibility problems , You need to add... To the configuration
BeanPostProcessorThis Bean, For details, please refer to upgrade SpringBoot 2.6.x After version ,Swagger It's useless ! ;
/**
* Swagger API Document related configuration
* 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);
}
}
};
}
}
- Before we passed
@ApiAnnotateddescriptionProperty to configure interface descriptions has been deprecated ;
- We can use
@TagAnnotation to configure the interface description , And use@ApiIn the annotationstagsProperty to specify .
Spring Security upgrade
upgrade Spring Boot 2.7.0 After version , Originally through inheritance WebSecurityConfigurerAdapter The method to configure has been deprecated , Just configure SecurityFilterChainBean that will do , Specific reference Spring Security The latest usage .
/**
* SpringSecurity 5.4.x The above new usage configuration
* To avoid circular dependencies , For configuration only 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();
// Resource paths that do not need to be protected allow access
for (String url : ignoreUrlsConfig.getUrls()) {
registry.antMatchers(url).permitAll();
}
// Allow cross domain requests for OPTIONS request
registry.antMatchers(HttpMethod.OPTIONS)
.permitAll();
// Any request requires authentication
registry.and()
.authorizeRequests()
.anyRequest()
.authenticated()
// Turn off cross station request protection and not use session
.and()
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// Custom permission denied processing class
.and()
.exceptionHandling()
.accessDeniedHandler(restfulAccessDeniedHandler)
.authenticationEntryPoint(restAuthenticationEntryPoint)
// Custom permission interceptor JWT filter
.and()
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// Add dynamic permission verification filter when there is dynamic permission configuration
if(dynamicSecurityService!=null){
registry.and().addFilterBefore(dynamicSecurityFilter, FilterSecurityInterceptor.class);
}
return httpSecurity.build();
}
}
MyBatis-Plus upgrade
MyBatis-Plus Upgraded from the previous version to 3.5.1 edition , The usage hasn't changed much , The biggest difference is that the usage of the code generator has been changed . In the previous usage, we passed new Object and then set Various properties to configure , Refer to the following code for details :
/**
* MyBatisPlus Code generator
* Created by macro on 2020/8/20.
*/
public class MyBatisPlusGenerator {
/**
* Initialize global configuration
*/
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;
}
}
And the new version MyBatis-Plus The code generator has been configured using builder mode instead , For details, please refer to MyBatisPlusGenerator Code in a class .
/**
* MyBatisPlus Code generator
* Created by macro on 2020/8/20.
*/
public class MyBatisPlusGenerator {
/**
* Initialize global configuration
*/
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();
}
}
Solve the problem of circular dependence
- Actually Spring Boot from 2.6.x Circular dependency is not recommended in version , If you use a lot of circular dependencies in your project , You can use the following configuration to enable ;
spring:
main:
allow-circular-references: true
- But since it is not recommended by the government , We'd better avoid circular dependency , Here are some ideas for me to solve the problem of circular dependency .
If there are multiple dependencies in a class , This class is not necessary Bean Don't configure it , You can use separate classes to configure Bean. such asSecurityConfigIn this configuration class , I only state what is necessarySecurityFilterChainTo configure ;
/**
* SpringSecurity 5.4.x The above new usage configuration
* To avoid circular dependencies , For configuration only 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 {
// Omit some codes ...
return httpSecurity.build();
}
}
- Other configurations have been moved to
CommonSecurityConfigConfiguration class , This avoids previous circular dependencies ;
/**
* SpringSecurity General configuration
* Including universal Bean、Security Universal Bean And dynamic permissions 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();
}
}
- There is also a typical circular dependency problem ,
UmsAdminServiceImplandUmsAdminCacheServiceImplInterdependence ;
/**
* Backstage administrator management Service Implementation class
* Created by macro on 2018/4/26.
*/
@Service
public class UmsAdminServiceImpl extends ServiceImpl<UmsAdminMapper,UmsAdmin> implements UmsAdminService {
@Autowired
private UmsAdminCacheService adminCacheService;
}
/**
* Background user cache management Service Implementation class
* Created by macro on 2020/3/13.
*/
@Service
public class UmsAdminCacheServiceImpl implements UmsAdminCacheService {
@Autowired
private UmsAdminService adminService;
}
- We can create one to get Spring In container Bean To implement ;
/**
* Spring Tool class
* Created by macro on 2020/3/3.
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
// obtain applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
// adopt name obtain Bean
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
// adopt class obtain Bean
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
// adopt name, as well as Clazz Returns the specified Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
- And then in
UmsAdminServiceImplUse this tool class to get Bean To solve circular dependency .
/**
* Backstage administrator management Service Implementation class
* 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);
}
}
Solving cross domain problems
In the use of Spring Boot 2.7.0 version , If you do not modify the previous cross domain configuration , Cross domain problems will occur through front-end access , The back-end error is as follows .
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.
Specifically, it means allowedOrigins Wildcards are no longer supported * The configuration of the , Change to use allowedOriginPatterns To set up , The specific configuration is modified as follows .
/**
* Global cross domain configuration
* Created by macro on 2019/7/27.
*/
@Configuration
public class GlobalCorsConfig {
/**
* Filters that allow cross domain calls
*/
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// Allow all domain names to make cross domain calls
config.addAllowedOriginPattern("*");
// This usage is in SpringBoot 2.7.0 Is no longer supported in
//config.addAllowedOrigin("*");
// Allow to send across cookie
config.setAllowCredentials(true);
// Release all original header information
config.addAllowedHeader("*");
// Allow all request methods to be called across domains
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
summary
Today I shared my open source project scaffolding mall-tiny, And its upgrade SpringBoot 2.7.0 The process of . When we were writing code , If some usage has been abandoned , Try to find new ways to use , This ensures that our code is elegant enough !
Project address
Open source is not easy , If you feel that the project is helpful, please click
StarSupport me !
https://github.com/macrozheng/mall-tiny
边栏推荐
- Analog electricity - what is the resistance?
- 深入解析著名的阿里云Log4j 漏洞
- 二维卷积——torch.nn.conv2d的使用
- Get the data of Tongcheng (elong) Hotel
- 0611~ self study class
- Getaverse, a distant bridge to Web3
- 0611~自习课
- Image information is displayed by browser: data:image/png; Base64, + image content
- Blackmagic Fusion Studio 18
- 单细胞代码解析-妇科癌症单细胞转录组及染色质可及性分析1
猜你喜欢

Use Matplotlib to simulate linear regression

Gan Development Series II (pggan, Singan)

The results of the second quarter online moving people selection of "China Internet · moving 2022" were announced

C language to achieve a static version of the address book

After separation, the impression notes are still difficult to live, but there are many coquettish operations

05mysql lock analysis

SV casts and constants

C language custom type explanation - structure

The use and Simulation of character and string library functions in C language

700. Search DFS method in binary search tree
随机推荐
简单测试JS代码
面会菜评论分析
Detailed explanation of ansible automatic operation and maintenance (V) the setting and use of variables in ansible, the use of jinja2 template and the encryption control of ansible
700. Search DFS method in binary search tree
High performance complexity analysis of wechat circle of friends
Wrote a few small pieces of code, broke the system, and was blasted by the boss
Use Matplotlib to simulate linear regression
Shardingsphere database read / write separation
Step by step introduction to the development framework based on sqlsugar (12) -- split the content of the page module into components to realize the division and rule processing
[wechat official account H5] authorization
微信朋友圈的高性能复杂度分析
C # print reports using fastreport.net
0701~放假总结
C language programming training topics: K characters in left-handed string, little Lele and Euclidean, printing arrow pattern, civil servant interview, poplar matrix
PXE高效批量网络装机
Mobile robot (IV) four axis aircraft
213. Looting II - Dynamic Planning
Is it safe for qiniu to open an account?
What are the pitfalls from single architecture to distributed architecture?
0612~quartz定时器框架