Spring Boot微服务开发实例——项目开发-后台接口管理项目!

通过对需求描述的分析可知,需要构建3个项目,即后台接口管理项目、促销活动微服务项目和网关项目。本节分别介绍这3个项目的开发过程。

后台接口管理项目

使用https://start.spring.io/工具新建promotion项目,导入开发工具。新建相关的package,整体项目结构如图11.1所示。

(1)在pom.xml文件中添加相关依赖,代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http:

//www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

https://

maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter

parent</artifactId>

<version>2.3.9.RELEASE</version>

<relativePath/> <!--lookup parent from

repository -->

</parent>

<groupId>com.example.promotion</groupId>

<artifactId>promotion</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>promotion</name>

<description>Promotion project for Spring

Boot</description>

<properties>

<java.version>1.8</java.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter

actuator</artifactId>

</dependency>

<dependency>

<groupId>io.micrometer</groupId>

<artifactId>micrometer-registry

prometheus</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data

jpa</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data

redis</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter

web</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter

test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit

vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter

log4j2</artifactId>

</dependency>

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-alibaba

dependencies</artifactId>

<version>2.2.5.RELEASE</version>

<type>pom</type>

<scope>import</scope>

</dependency>

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-starter-alibaba-nacos

config

</artifactId>

<version>2.2.5.RELEASE</version>

</dependency>

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-starter-alibaba-nacos

discovery

</artifactId>

<version>2.2.5.RELEASE</version>

</dependency>

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-starter-alibaba

sentinel</artifactId>

<version>2.2.5.RELEASE</version>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<dependency>

<groupId>cn.hutool</groupId>

<artifactId>hutool-all</artifactId>

<version>5.2.3</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-pool2</artifactId>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-lang3</artifactId>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot

maven-plugin</artifactId>

<configuration>

<excludes>

<exclude>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

</exclude>

</excludes>

</configuration>

</plugin>

</plugins>

</build>

</project>

(2)修改application.xml配置文件,在其中配置数据库的连接方式,代码如下:

server:

port: 8080

spring:

application:

name: promotion

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://127.0.0.1:3306/test?

useUnicode=true&character

Encoding=utf8

username: test

password: test

type: com.zaxxer.hikari.HikariDataSource

hikari:

minimum-idle: 10

maximum-pool-size: 100

auto-commit: true

idle-timeout: 30000

pool-name: UserHikariCP

max-lifetime: 1800000

connection-timeout: 30000

jpa:

database: MYSQL

hibernate:

ddl-auto: none

show-sql: true

(3)由于集成了Nacos和Sentinel中间件,因此需要bootstrap.xml配置文件,具体配置如下:

spring:

cloud:

nacos:

discovery:

server-addr: 127.0.0.1:8848

ip: 127.0.0.1

port: 80

namespace: 40421527-56ff-410b-8ca8-e025aca9e946

group: default

config:

server-addr: 127.0.0.1:8848

file-extension: properties

namespace: 40421527-56ff-410b-8ca8-e025aca9e946

group: default

sentinel:

enabled: true

transport:

dashboard: 127.0.0.1:8888

clientIp: 127.0.0.1

port: 8719

log:

dir: /log/sentinel

filter:

enabled: false

management:

endpoint:

metrics:

enabled: true

prometheus:

enabled: true

endpoints:

web:

base-path: /

exposure:

include: health,info,status,prometheus

metrics:

export:

prometheus:

enabled: true

tags:

application: ${spring.application.name}

web:

server:

request:

autotime:

enabled: true

percentiles-histogram: on

percentiles:

-0.9

-0.99

client:

request:

autotime:

enabled: true

percentiles-histogram: on

percentiles:

-0.9

-0.99

(4)本例使用log4j2日志架构,配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN">

<properties>

<property name="LOG_HOME">/log</property>

</properties>

<Appenders>

<Console name="CONSOLE" target="SYSTEM_OUT" >

<PatternLayout pattern="%d{yyyy-MM-dd

HH:mm:ss.SSS} %-5p

[%t] %c{1.} %msg%n"/>

</Console>

<RollingRandomAccessFile name="INFO_FILE" fileName=

"${LOG_HOME}/info.log"

filePattern="${LOG_HOME}/info-%d{HH}

-%i.log" immediateFlush="true">

<PatternLayout pattern="%d{yyyy-MM-dd

HH:mm:ss.SSS}

[%traceId] %-5p %c{1.} %msg%n"/>

<Policies>

<TimeBasedTriggeringPolicy />

</Policies>

<DefaultRolloverStrategy max="1"/>

<Filters>

<ThresholdFilter level="error"

onMatch="ACCEPT" onMismatch=

"NEUTRAL"/>

<ThresholdFilter level="info"

onMatch="ACCEPT" onMismatch=

"DENY"/>

</Filters>

</RollingRandomAccessFile>

</Appenders>

<Loggers>

<Root level="info">

<AppenderRef ref="CONSOLE" />

<AppenderRef ref="INFO_FILE" />

</Root>

</Loggers>

</Configuration>

(5)将Redis配置信息集成到Nacos上,配置详情如图11.2所示。

具体的Redis信息如下:

redis.promotion.host=127.0.0.1

redis.promotion.port=6379

redis.promotion.password=test

redis.promotion.maxTotal=2000

redis.promotion.maxIdle=100

redis.promotion.minIdle=40

redis.promotion.maxWaitMillis=3000

redis.promotion.timeBetweenEvictionRunsMillis=30000

redis.promotion.commandTimeout=3000

(6)Redis自动配置:

新建RedisProperties.class文件,代码如下:

package com.example.promotion.config;

import lombok.Data;

import

org.springframework.boot.context.properties.Configuration

Properties;

@Data

@ConfigurationProperties(prefix = "redis")

public class RedisProperties {

private RedisInfo promotion;

@Data

public static class RedisInfo{

protected int maxTotal = 2000;

//最大连接数

protected int maxIdle = 100;

//最大空闲数

protected int minIdle = 40;

//最小空闲数

protected int maxWaitMillis = 3000;

//最长等待时间

//空闲回收休眠时间

protected int timeBetweenEvictionRunsMillis = 30000;

protected int commandTimeout = 3000; //命令

执行超时时间

private String host;

//Redis地址

private int port;

//Redis端口

private String password;

//Redis密码

}

}

新建
RedisAutoConfiguration.class文件,代码如下:

package com.example.promotion.config;

import java.time.Duration;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import

org.springframework.boot.autoconfigure.condition.Conditional

OnClass;

import

org.springframework.boot.autoconfigure.condition.Conditional

OnProperty;

import

org.springframework.boot.context.properties.EnableConfigurati

on

Properties;

import

org.springframework.cloud.context.config.annotation.Refresh

Scope;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import

org.springframework.data.redis.connection.RedisStandalone

Configuration;

import

org.springframework.data.redis.connection.lettuce.Lettuce

ClientConfiguration;

import

Org.springframework.data.redis.connection.lettuce.Lettuce

ConnectionFactory;

import

org.springframework.data.redis.connection.lettuce.Lettuce

PoolingClientConfiguration;

import

org.springframework.data.redis.core.StringRedisTemplate;

@ConditionalOnClass(LettuceConnectionFactory.class)

@Configuration

@EnableConfigurationProperties(RedisProperties.class)

@ConditionalOnProperty("redis.promotion.host")

public class RedisAutoConfiguration {

@Bean

@RefreshScope

public GenericObjectPoolConfig

genericObjectPoolConfig(Redis

Properties properties) {

//通用线程池配置

GenericObjectPoolConfig genericObjectPoolConfig = new

Generic

ObjectPoolConfig();

//设置最大的连接数

genericObjectPoolConfig.setMaxTotal(properties.getPromotion()

.

getMaxTotal());

//设置最大的空闲数

genericObjectPoolConfig.setMaxIdle(properties.getPromotion().

getMaxIdle());

//设置最小的空闲数

genericObjectPoolConfig.setMinIdle(properties.getPromotion().

getMinIdle());

//设置最长的等待时间

genericObjectPoolConfig.setMaxWaitMillis(properties.get

Promotion().getMaxWaitMillis());

//从连接池取出连接时检查有效性

genericObjectPoolConfig.setTestOnBorrow(true);

//连接返回时检查有效性

genericObjectPoolConfig.setTestOnReturn(true);

//空闲时检查有效性

genericObjectPoolConfig.setTestWhileIdle(true);

//空闲回收休眠时间

genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis

(properties.getPromotion().getTimeBetweenEvictionRunsMillis()

);

return genericObjectPoolConfig;

}

@Bean

@RefreshScope

public LettuceClientConfiguration

lettuceClientConfiguration

(RedisProperties properties, GenericObjectPoolConfig

genericObject

PoolConfig) {

//Lettuce客户端配置

LettucePoolingClientConfiguration build =

LettucePooling

ClientConfiguration.builder()

.commandTimeout(Duration.ofMillis(properties.get

Promotion().getCommandTimeout()))

.shutdownTimeout(Duration.ZERO)

.poolConfig(genericObjectPoolConfig)

.build();

return build;

}

@Bean

@RefreshScope

public LettuceConnectionFactory

lettuceConnectionFactory(Redis

Properties properties,

LettuceClientConfiguration lettuceClientConfiguration) {

//Redis配置

RedisStandaloneConfiguration redisConfiguration = new

Redis

StandaloneConfiguration(properties.getPromotion().getHost(),

properties.

getPromotion().getPort());

redisConfiguration.setPassword(properties.getPromotion().

getPassword());

//Lettuce连接工厂

LettuceConnectionFactory lettuceConnectionFactory =

new Lettuce

ConnectionFactory(redisConfiguration,

lettuceClientConfiguration);

return lettuceConnectionFactory;

}

@Bean(name = "redisTemplate")

public StringRedisTemplate

stringRedisTemplate(LettuceConnection

Factory lettuceConnectionFactory) {

//RedisTemplate声明

return new

StringRedisTemplate(lettuceConnectionFactory);

}

}

(7)新增Sentinel切面配置,代码如下:

package com.example.promotion.config;

import

com.alibaba.csp.sentinel.annotation.aspectj.SentinelResource

Aspect;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class SentinelConfig {

@Bean

public SentinelResourceAspect sentinelResourceAspect() {

//Sentinel切面声明

return new SentinelResourceAspect();

}

}

(8)新建Model层的对象PromotionEntyty,代码如下:

package com.example.promotion.model;

import java.io.Serializable;

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.EntityListeners;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.Table;

import org.springframework.data.annotation.CreatedDate;

import org.springframework.data.annotation.LastModifiedDate;

import

org.springframework.data.jpa.domain.support.AuditingEntity

Listener;

import lombok.Data;

@Entity

@Table(name="promotion")

//声明表名

@Data

@EntityListeners(AuditingEntityListener.class)

public class PromotionEntity implements Serializable {

private static final long serialVersionUID = 1L;

//主键ID

@Id

@Column(name="id")

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Integer id;

//促销活动的名称

@Column(name="name")

private String name;

//促销活动的开始时间

@Column(name="begin_time")

private Integer beginTime;

//促销活动的结束时间

@Column(name="end_time")

private Integer endTime;

//奖品

@Column(name="prize")

private String prize;

//创建时间

@Column(name="create_time")

@CreatedDate

private Date createTime;

//更新时间

@Column(name="update_time")

@LastModifiedDate

private Date updateTime;

}

(9)本例采用Spring Boot JPA。Repository代码如下:

package com.example.promotion.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import com.example.promotion.model.PromotionEntity;

@Repository

public interface PromotionRepository extends

JpaRepository<Promotion

Entity,Integer>{

//自定义查询

PromotionEntity findByName(String name);

}

(10)接口返回通用状态码及Redis操作key的声明。

新增Constant.class文件,代码如下:

package com.example.promotion.constants;

public class Constant {

//接口调用成功,返回成功状态码

public static final String SUCCESS_CODE = "S00000";

//接口失败,则返回状态码

public static final String ERROR_CODE = "F00001";

//接口成功返回信息

public static final String SUCCESS_MSG = "success";

//促销活动Redis存储key,用来存储活动信息

public static final String REDIS_PROMOTION_KEY =

"promotion:{0}";

//赠送奖品领取记录

public static final String REDIS_PRIZE_KEY =

"promotion:{0}:{1}";

}

新建AbstractResponse.class文件,代码如下:

package com.example.promotion.constants;

//通用返回类

public class AbstractResponse {

private String code;

private String msg;

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public String getMsg() {

return msg;

}

public void setMsg(String msg) {

this.msg = msg;

}

新建JsonObjectResponse.class文件,代码如下:

package com.example.promotion.constants;

//扩展返回类

public class JsonObjectResponse<T> extends AbstractResponse {

private T result;

public T getResult() {

return result;

}

public void setResult(T result) {

this.result = result;

}

public JsonObjectResponse(T result, String code,

String msg) {

this.setCode(code);

this.setMsg(msg);

this.result = result;

}

public JsonObjectResponse(T result) {

this.setCode(Constant.SUCCESS_CODE);

this.setMsg(Constant.SUCCESS_MSG);

this.result = result;

}

public JsonObjectResponse() {

this.setCode(Constant.SUCCESS_CODE);

this.setMsg(Constant.SUCCESS_MSG);

this.result = null;

}

public JsonObjectResponse(String code, String msg) {

this.setCode(code);

this.setMsg(msg);

}

}

(11)PromotionController接口代码如下:

package com.example.promotion.controller;

import org.apache.commons.lang.StringUtils;

import

org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.DeleteMapping;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import

org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import

org.springframework.web.bind.annotation.RestController;

import com.alibaba.csp.sentinel.EntryType;

import com.alibaba.csp.sentinel.annotation.SentinelResource;

import com.example.promotion.constants.Constant;

import com.example.promotion.constants.JsonObjectResponse;

import com.example.promotion.model.PromotionEntity;

import com.example.promotion.service.BlockHandlerService;

import com.example.promotion.service.FallBackService;

import com.example.promotion.service.PromotionService;

import lombok.extern.slf4j.Slf4j;

@Slf4j

@RestController

@RequestMapping("/api")

public class PromotionController {

@Autowired

private PromotionService promotionService;

//查询促销活动接口,路径:/api/queryPromotion?id=xx

@GetMapping("queryPromotion")

@ResponseBody

//限流与降级注解

@SentinelResource(value = "queryPromotion", entryType

= EntryType.IN,

blockHandler = "queryPromotionBlockHandle", blockHandlerClass

=

{BlockHandlerService.class}, defaultFallback = "fallback",

fallback

Class = {FallBackService.class})

public JsonObjectResponse<PromotionEntity>

queryPromotion

(Integer id) {

try {

//调用促销活动服务类查询方法

return

promotionService.queryPromotion(id);

} catch (Exception e) {

//记录错误日志

log.error("query promotion error!");

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"query promotion error!");

}

}

//提交促销活动接口,路径:/api/addPromotion

//参数:PromotionEntity

@PostMapping("addPromotion")

@ResponseBody

@SentinelResource(value = "addPromotion", entryType =

EntryType.IN,

blockHandler = "addPromotionBlockHandle", blockHandlerClass =

{BlockHandlerService.class}, defaultFallback = "fallback",

fallback

Class = {FallBackService.class})

public JsonObjectResponse<PromotionEntity>

addPromotion

(PromotionEntity promotionEntity) {

if

(StringUtils.isBlank(promotionEntity.getName()) ||

StringUtils.

isBlank(promotionEntity.getPrize())) {

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"param is null! ");

}

try {

//调用促销活动服务类新增方法

return

promotionService.addPromotion(promotionEntity);

} catch (Exception e) {

//记录错误日志

log.error("add promotion error!");

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"add promotion error!");

}

}

//更新促销活动接口,路径:/api/updatePromotion

//参数:PromotionEntity

@PostMapping("updatePromotion")

@ResponseBody

@SentinelResource(value = "updatePromotion",

entryType = EntryType.IN,

blockHandler = "updatePromotionBlockHandle",

blockHandlerClass =

{BlockHandlerService.class}, defaultFallback = "fallback",

fallback

Class = {FallBackService.class})

public JsonObjectResponse<PromotionEntity>

updatePromotion

(PromotionEntity promotionEntity) {

if (promotionEntity.getId() == null) {

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"id is null! ");

}

try {

//调用促销活动服务类更新方法

return

promotionService.updatePromotion(promotionEntity);

} catch (Exception e) {

//记录错误日志

log.error("add promotion error!");

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"add promotion error!");

}

}

//删除促销活动接口,路径:/api/delPromotion?id=xx

@DeleteMapping("delPromotion")

@ResponseBody

@SentinelResource(value = "delPromotion", entryType =

EntryType.IN,

blockHandler = "delPromotionBlockHandle", blockHandlerClass =

{BlockHandlerService.class}, defaultFallback = "fallback",

fallback

Class = {FallBackService.class})

public JsonObjectResponse<PromotionEntity>

delPromotion(Integer

id) {

try {

//调用删除服务类方法

return

promotionService.delPromotion(id);

} catch (Exception e) {

//记录错误日志

log.error("delete promotion error!");

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"delete promotion error!");

}

}

}

(12)PromotionService代码如下:

package com.example.promotion.service;

import java.text.MessageFormat;

import java.util.HashMap;

import java.util.Map;

import java.util.Optional;

import

org.springframework.beans.factory.annotation.Autowired;

import

org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Service;

import com.example.promotion.constants.Constant;

import com.example.promotion.constants.JsonObjectResponse;

import com.example.promotion.model.PromotionEntity;

import com.example.promotion.repository.PromotionRepository;

import lombok.extern.slf4j.Slf4j;

//促销活动服务类

@Service

@Slf4j

public class PromotionService {

//PromotionRepository注入

@Autowired

private PromotionRepository promotionRepository;

//StringRedisTemplate注入

@Autowired

private StringRedisTemplate stringRedisTemplate;

//查询促销活动信息

public JsonObjectResponse<PromotionEntity>

queryPromotion(Integer

id) {

Optional<PromotionEntity> promotionEntity =

promotionRepository.

findById(id);

if (promotionEntity.isPresent()) {

return new JsonObjectResponse<>

(promotionEntity.get());

} else {

return new JsonObjectResponse<>

(null);

}

}

//添加促销活动信息

public JsonObjectResponse<PromotionEntity>

addPromotion(Promotion

Entity promotionEntity) {

PromotionEntity promotionEntityOld =

promotionRepository.

findByName(promotionEntity.getName());

if (promotionEntityOld != null) { //查询

促销活动是否已经存在

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"promotion name is exist!");

} else {

//如果不存在,则添加

PromotionEntity promotionEntityNew =

promotionRepository.

save(promotionEntity);

//插入MySQL数据库

String key =

MessageFormat.format(Constant.REDIS_PROMOTION_

KEY, String.valueOf(promotionEntityNew.getId()));

Map<String, String> map = new

HashMap<>();

map.put("name",

promotionEntityNew.getName());

map.put("beginTime",

String.valueOf(promotionEntityNew.

getBeginTime()));

map.put("endTime",

String.valueOf(promotionEntityNew.

getEndTime()));

map.put("prize",

promotionEntityNew.getPrize());

//添加到Redis中

stringRedisTemplate.opsForHash().putAll(key, map);

log.info("addPromotion success");

}

return new JsonObjectResponse<>(null);

}

//更新促销活动信息

public JsonObjectResponse<PromotionEntity>

updatePromotion(Promotion

Entity promotionEntity) {

Optional<PromotionEntity> promotionEntityOpt

= promotion

Repository.findById(promotionEntity.getId());

if (promotionEntityOpt.isPresent()) {

PromotionEntity promotionEntityOld =

promotionEntityOpt.

get();

promotionEntityOld.setName(promotionEntity.getName());

promotionEntityOld.setPrize(promotionEntity.getPrize());

promotionEntityOld.setBeginTime(promotionEntity.getBegin

Time());

promotionEntityOld.setEndTime(promotionEntity.getEndTime());

//更新MySQL信息

promotionRepository.save(promotionEntityOld);

String key =

MessageFormat.format(Constant.REDIS_PROMOTION_

KEY, String.valueOf(promotionEntityOld.getId()));

Map<String, String> map = new

HashMap<>();

map.put("name",

promotionEntityOld.getName());

map.put("beginTime",

String.valueOf(promotionEntityOld.

getBeginTime()));

map.put("endTime",

String.valueOf(promotionEntityOld.

getEndTime()));

map.put("prize",

promotionEntityOld.getPrize());

//更新Redis信息

stringRedisTemplate.opsForHash().putAll(key, map);

log.info("updatePromotion success");

}

return new JsonObjectResponse<>(null);

}

//删除促销活动信息

public JsonObjectResponse<PromotionEntity>

delPromotion(Integer

id) {

promotionRepository.deleteById(id);

//删除MySQL信息

String key =

MessageFormat.format(Constant.REDIS_PROMOTION_

KEY, String.valueOf(id));

stringRedisTemplate.delete(key);

//删除Redis信息

log.info("delPromotion success");

return new JsonObjectResponse<>(null);

}

}

(13)限流代码如下:

package com.example.promotion.service;

import com.example.promotion.constants.Constant;

import com.example.promotion.constants.JsonObjectResponse;

import com.example.promotion.model.PromotionEntity;

//接口发生限流时触发

public final class BlockHandlerService {

public static JsonObjectResponse<PromotionEntity>

queryPromotion

BlockHandle(Integer id) {

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"queryPromotion blcok");

}

public static JsonObjectResponse<PromotionEntity>

addPromotion

BlockHandle(PromotionEntity promotionEntity) {

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"addPromotion blcok");

}

public static JsonObjectResponse<PromotionEntity>

updatePromotion

BlockHandle(PromotionEntity promotionEntity) {

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"updatePromotion blcok");

}

public static JsonObjectResponse<PromotionEntity>

delPromotion

BlockHandle(Integer id) {

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"delPromotion blcok");

}

}

(14)降级代码如下:

package com.example.promotion.service;

import com.example.promotion.constants.Constant;

import com.example.promotion.constants.JsonObjectResponse;

import com.example.promotion.model.PromotionEntity;

//接口发生降级时触发

public final class FallBackService {

public static JsonObjectResponse<PromotionEntity>

defaultFall

Back(Throwable ex){

return new JsonObjectResponse<>(null,

Constant.ERROR_CODE,

"fallback");

}

}

(15)PromotionApplication代码如下:

package com.example.promotion;

import org.springframework.boot.SpringApplication;

import

org.springframework.boot.autoconfigure.SpringBootApplication;

import

org.springframework.boot.autoconfigure.data.redis.RedisAuto

Configuration;

import

org.springframework.cloud.client.discovery.EnableDiscovery

Client;

import

org.springframework.context.annotation.EnableAspectJAutoProxy

;

import

org.springframework.data.jpa.repository.config.EnableJpaAudit

ing;

//自定义Redis配置

@SpringBootApplication(exclude =

{RedisAutoConfiguration.class})

@EnableJpaAuditing

//开启JPA审计

@EnableAspectJAutoProxy

//开启切面

@EnableDiscoveryClient

//开启服务发现

public class PromotionApplication {

public static void main(String[] args) {

SpringApplication.run(PromotionApplication.class, args);

}

}

此时,启动PromotionApplication主类即可访问接口,管理促销活动信息。例如添加一条活动信息,访问接口
http://localhost:8080/api/addPromotion,设置参数如下:

name:"会员促销活动"

beginTime:"1614822680"

endTime:" 1617176808"

prize:"3天免费会员"

访问查询接口
http://localhost:8080/api/queryPromotion?

id=1,返回结果如下:

{

code: "S00000",

msg: "success",

result: {

id: 3,

name: "会员促销活动",

beginTime: 1614822680,

endTime: 1617176808,

prize: "3天免费会员",

createTime: "2021-03-05T03:57:35.000+00:00",

updateTime: "2021-03-05T03:59:12.000+00:00"

}

}

访问更新接口
http://localhost:8080/api/updatePromotion,添加参数即可修改促销活动信息,参数如下:

id:1

name:"会员促销活动"

beginTime:"1614822680"

endTime:" 1617176808"

prize:"3天免费会员"

访问删除接口
http://localhost:8080/api/ delPromotion?id=1,即可删除该促销活动信息.

原文链接:,转发请注明来源!