Реальный боевой проект Mall электронной коммерции выпустил крупное обновление, полностью поддерживающее SpringBoot 2.3.0!

Spring Boot Java
Реальный боевой проект Mall электронной коммерции выпустил крупное обновление, полностью поддерживающее SpringBoot 2.3.0!

Адрес фактического центра электронной коммерции SpringBoot (39k+star):GitHub.com/macro-positive/…

Резюме

Раньше я писал много статей, посвященных основным технологиям, и многие друзья отзывались о том, что именно эту технологию они хотят изучать! Если эти методы подходят, я буду использовать их в своих проектах с открытым исходным кодом. недавнийmallОбновление и изменения проекта все еще относительно велики, поэтому я написал статью, чтобы представить обновленный контент, надеясь помочь всем!

Список обновленного содержимого

  • Обновление до SpringBoot 2.3.0.RELEASE;
  • Поддержка Elasticsearch версии 7.6.2;
  • Завершена функция сбора логов ELK, принята схема сбора логов в разных сценариях;
  • Конфигурация Swagger унифицирована, что упрощает настройку;
  • Конфигурация Redis унифицирована, что упрощает настройку;
  • Обновлена ​​документация по развертыванию Windows и Linux.

Обновить введение контента

Обновите SpringBoot 2.3.0

До этого я использовал SpringBoot версии 2.1.7, эта версия была выпущена в августе 2019. Прошло уже больше года, и пришло время обновить версию. SpringBoot 2.3.0 был выпущен в мае этого года, и это все еще относительно новая версия, друзья, которые хотят узнать о новых возможностях этой версии, могут прочитать ее.«Список новых функций SpringBoot 2.3.0, приходите и попрактикуйтесь со мной! 》.

Поддержка Elasticsearch 7.6.2

Из-за обновления версии SpringBoot Elasticsearch был вынужден обновиться, и, конечно же, Elasticsearch 7.x теперь также является основной версией. Я наступил на много ям в процессе апгрейда, можете посмотреть подробности«После обновления Elasticsearch до версии 7.x я чувствую, что попал в яму! 》.

Функция сбора журнала ELK идеальна

Предыдущая функция сбора логов не была идеальной, и метод сбора логов в разных сценариях не был принят, в этот раз его наконец-то улучшили. Для построения системы сбора журналов и решения для сбора журналов в различных сценариях см."Вы все равно ходите на сервер собирать логи, разве не восхитительно настроить систему сбора логов! 》.

Единая конфигурация Swagger

Раньше у каждого модуля была своя конфигурация Swagger, напримерmall-admin,mall-portalиmall-searchУ каждого своя конфигурация, которая была унифицирована.

  • первый вmall-commonВ модуль добавлена ​​базовая конфигурация SwaggerBaseSwaggerConfig, используйте в других модулях, просто наследуйте конфигурацию и переопределяйтеswaggerProperties()Этого абстрактного метода достаточно;
/**
 * Swagger基础配置
 * Created by macro on 2020/7/16.
 */
public abstract class BaseSwaggerConfig {

    @Bean
    public Docket createRestApi() {
        SwaggerProperties swaggerProperties = swaggerProperties();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo(swaggerProperties))
                .select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getApiBasePackage()))
                .paths(PathSelectors.any())
                .build();
        if (swaggerProperties.isEnableSecurity()) {
            docket.securitySchemes(securitySchemes()).securityContexts(securityContexts());
        }
        return docket;
    }

    private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(), swaggerProperties.getContactEmail()))
                .version(swaggerProperties.getVersion())
                .build();
    }

    private List<ApiKey> securitySchemes() {
        //设置请求头信息
        List<ApiKey> result = new ArrayList<>();
        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
        result.add(apiKey);
        return result;
    }

    private List<SecurityContext> securityContexts() {
        //设置需要登录认证的路径
        List<SecurityContext> result = new ArrayList<>();
        result.add(getContextByPath("/*/.*"));
        return result;
    }

    private SecurityContext getContextByPath(String pathRegex) {
        return SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex(pathRegex))
                .build();
    }

    private List<SecurityReference> defaultAuth() {
        List<SecurityReference> result = new ArrayList<>();
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        result.add(new SecurityReference("Authorization", authorizationScopes));
        return result;
    }

    /**
     * 自定义Swagger配置
     */
    public abstract SwaggerProperties swaggerProperties();
}
  • один из нихSwaggerPropertiesКласс — это наш настраиваемый класс конфигурации, какие там конфигурации, просто посмотрите комментарии, чтобы было понятно;
/**
 * Swagger自定义配置
 * Created by macro on 2020/7/16.
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Builder
public class SwaggerProperties {
    /**
     * API文档生成基础路径
     */
    private String apiBasePackage;
    /**
     * 是否要启用登录认证
     */
    private boolean enableSecurity;
    /**
     * 文档标题
     */
    private String title;
    /**
     * 文档描述
     */
    private String description;
    /**
     * 文档版本
     */
    private String version;
    /**
     * 文档联系人姓名
     */
    private String contactName;
    /**
     * 文档联系人网址
     */
    private String contactUrl;
    /**
     * 文档联系人邮箱
     */
    private String contactEmail;
}
  • существуетmall-adminмодуль, просто наследуйBaseSwaggerConfigи настроитьSwaggerPropertiesВот именно, не очень удобно!
/**
 * Swagger API文档相关配置
 * Created by macro on 2018/4/26.
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig extends BaseSwaggerConfig {

    @Override
    public SwaggerProperties swaggerProperties() {
        return SwaggerProperties.builder()
                .apiBasePackage("com.macro.mall.controller")
                .title("mall后台系统")
                .description("mall后台相关接口文档")
                .contactName("macro")
                .version("1.0")
                .enableSecurity(true)
                .build();
    }
}

Единая конфигурация Redis

При использовании Redis мы более или менее настраиваем некоторые конфигурации, которые теперь унифицированы.

  • первый вmall-commonВ модуль добавлена ​​базовая конфигурация RedisBaseRedisConfig, вам нужно только наследовать эту конфигурацию, чтобы использовать ее в других модулях;
/**
 * Redis基础配置
 * Created by macro on 2020/6/19.
 */
public class BaseRedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisSerializer<Object> serializer = redisSerializer();
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public RedisSerializer<Object> redisSerializer() {
        //创建JSON序列化器
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //必须设置,否则无法将JSON转化为对象,会转化成Map类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }

    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        //设置Redis缓存有效期为1天
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofDays(1));
        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }


    @Bean
    public RedisService redisService(){
        return new RedisServiceImpl();
    }

}
  • Например, мыmall-securityВ модуле необходимо использовать Redis, а конфигурация может быть напрямую унаследована;
/**
 * Redis配置类
 * Created by macro on 2020/3/2.
 */
@EnableCaching
@Configuration
public class RedisConfig extends BaseRedisConfig {

}
  • Когда вам нужно управлять Redis, внедряйте напрямуюRedisServiceобъекта, а затем использовать его для работы.
/**
 * UmsAdminCacheService实现类
 * Created by macro on 2020/3/13.
 */
@Service
public class UmsAdminCacheServiceImpl implements UmsAdminCacheService {
    @Autowired
    private RedisService redisService;
}

Обновления документации по развертыванию Windows и Linux

В связи с обновлением некоторых компонентов документация по развертыванию также была обновлена.Три метода развертывания, всегда найдется подходящий для вас!

адрес проекта

Если вы считаете проект мощным, пожалуйста, нажмитеStarПоддержите это!

GitHub.com/macro-positive/…