前言
本集成为:双消费者,双生产者,双注册中心,熔断器,服务网关,SSM
,Redis
,Mybatis
自动生成,PageHelper
分页插件
二、版本说明
SpringCloud:Hoxton.RELEASE
SpringBoot:2.2.2
四、上代码
1)创建主项目
我们一步步来,创建主项目WXbackgroud
maven的quickstart项目
pom依赖
<?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.2.2.RELEASE</version>
</parent>
<groupId>com.zking</groupId>
<artifactId>WXBackgroud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>WXBackgroud</name>
<description>主模块-WXBackgroud</description>
<packaging>pom</packaging>
<modules>
<module>wxbackgroud-server-cluster</module>
<module>wxbackgroud-provider</module>
<module>wxbackgroud-hystrix</module>
<module>wxbackgroud-gateway</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
<!--<spring-cloud.version>Greenwich.SR3</spring-cloud.version>-->
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.zking</groupId>
<artifactId>wxbackgroud-vo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2)创建双注册中心wxbackgroud-server-cluster
pom依赖
<?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>com.zking</groupId>
<artifactId>WXBackgroud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wxbackgroud-server-cluster</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxbackgroud-server-cluster</name>
<packaging>jar</packaging>
<description>子模块之注册中心</description>
</project>
yml配置文件
---
server:
port: 7101
spring:
profiles: peer1
application:
name: wxbackgroud-server-cluster
eureka:
instance:
hostname: peer1
client:
# registerWithEureka: true
# fetchRegistry: true
serviceUrl:
defaultZone: http://peer2:7102/eureka/
---
server:
port: 7102
spring:
profiles: peer2
application:
name: wxbackgroud-server-cluster
eureka:
instance:
hostname: peer2
client:
# registerWithEureka: true
# fetchRegistry: true
serviceUrl:
defaultZone: http://peer1:7101/eureka/
运行类打上注解
package com.zking.wxbackgroudservercluster;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class WxbackgroudServerClusterApplication {
public static void main(String[] args) {
SpringApplication.run(WxbackgroudServerClusterApplication.class, args);
}
}
3)双生产者wxbackgrou-provider
pom依赖
<?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>com.zking</groupId>
<artifactId>WXBackgroud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wxbackgroud-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxbackgroud-provider</name>
<packaging>jar</packaging>
<description>子模块之生产者</description>
<properties>
<java.version>1.8</java.version>
<druid.version>1.1.10</druid.version>
<mybatis.version>2.1.1</mybatis.version>
<mysql.version>5.1.44</mysql.version>
<mybatis-generator.version>1.3.2</mybatis-generator.version>
<pagehelper.version>1.2.3</pagehelper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>${mysql.version}</version>
</dependency>
<!-- druid 连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--generator-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>${mybatis-generator.version}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml
src/main/resources
**/ *.xml</include>
<include>**/*.yml
**/ *.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>${mybatis-generator.version}</version>
<dependencies>
<!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<configuration>
<!--<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>-->
<!--允许移动生成的文件 -->
<!--<verbose>true</verbose>-->
<!-- 是否覆盖 -->
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
</project>
yml配置文件
---
# 端口号
server:
port: 7201
# 服务名称
spring:
profiles: provider1
application:
name: wxbackgroud-provider
datasource:
#1.JDBC
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123
druid:
#2.连接池配置
#初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
url-pattern: /druid/*
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: admin
allow: 127.0.0.1
#deny: 192.168.1.100
redis:
database: 0
host: 192.168.208.130
port: 6379
password: 123456
jedis:
pool:
max-active: 100
max-idle: 3
max-wait: -1
min-idle: 0
timeout: 1000
mybatis:
#配置SQL映射文件路径
mapper-locations: classpath:mapper/*.xml
#配置别名
type-aliases-package: com.zking.wxbackgroudprovider.model
#驼峰命名规则
configuration:
map-underscore-to-camel-case: true
#pagehelper分页插件配置
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
#显示日志
logging:
level:
com.zking.springboot02.mapper: debug
# 服务注册与发现相关配置
eureka:
client:
# 注册中心地址
serviceUrl:
defaultZone: http://peer1:7101/eureka/,http://peer2:7102/eureka/
---
# 端口号
server:
port: 7202
# 服务名称
spring:
profiles: provider2
application:
name: wxbackgroud-provider
datasource:
#1.JDBC
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123
druid:
#2.连接池配置
#初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
url-pattern: /druid/*
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: admin
allow: 127.0.0.1
#deny: 192.168.1.100
redis:
database: 0
host: 192.168.208.130
port: 6379
password: 123456
jedis:
pool:
max-active: 100
max-idle: 3
max-wait: -1
min-idle: 0
timeout: 1000
mybatis:
#配置SQL映射文件路径
mapper-locations: classpath:mapper/*.xml
#配置别名
type-aliases-package: com.zking.wxbackgroudprovider.model
#驼峰命名规则
configuration:
map-underscore-to-camel-case: true
#pagehelper分页插件配置
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
#显示日志
logging:
level:
com.zking.springboot02.mapper: debug
# 服务注册与发现相关配置
eureka:
client:
# 注册中心地址
serviceUrl:
defaultZone: http://peer1:7101/eureka/,http://peer2:7102/eureka/
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
<!-- 引入配置文件 -->
<properties resource="jdbc.properties"/>
<!--指定数据库jdbc驱动jar包的位置-->
<classPathEntry location="E:\repository\mvn-repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/>
<!-- 一个数据库一个context -->
<context id="infoGuardian">
<!-- 注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/><!-- 是否取消注释 -->
<property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 -->
</commentGenerator>
<!-- jdbc连接 -->
<jdbcConnection driverClass="${jdbc.driver}"
connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
<!-- 类型转换 -->
<javaTypeResolver>
<!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 01 指定javaBean生成的位置 -->
<!-- targetPackage:指定生成的model生成所在的包名 -->
<!-- targetProject:指定在该项目下所在的路径 -->
<javaModelGenerator targetPackage="com.zking.wxbackgroudprovider.model"
targetProject="src/main/java">
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="false"/>
<!-- 是否对model添加构造函数 -->
<property name="constructorBased" value="true"/>
<!-- 是否针对string类型的字段在set的时候进行trim调用 -->
<property name="trimStrings" value="false"/>
<!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 -->
<property name="immutable" value="false"/>
</javaModelGenerator>
<!-- 02 指定sql映射文件生成的位置 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<!-- 是否允许子包,即targetPackage.schemaName.tableName -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!-- 03 生成XxxMapper接口 -->
<!-- type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 -->
<!-- type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 -->
<!-- type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
<javaClientGenerator targetPackage="com.zking.wxbackgroudprovider.mapper"
targetProject="src/main/java" type="XMLMAPPER">
<!-- 是否在当前路径下新加一层schema,false路径com.oop.eksp.user.model, true:com.oop.eksp.user.model.[schemaName] -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 配置表信息 -->
<!-- schema即为数据库名 -->
<!-- tableName为对应的数据库表 -->
<!-- domainObjectName是要生成的实体类 -->
<!-- enable*ByExample是否生成 example类 -->
<!--<table schema="" tableName="t_book" domainObjectName="Book"-->
<!--enableCountByExample="false" enableDeleteByExample="false"-->
<!--enableSelectByExample="false" enableUpdateByExample="false">-->
<!--<!– 忽略列,不生成bean 字段 –>-->
<!--<!– <ignoreColumn column="FRED" /> –>-->
<!--<!– 指定列的java数据类型 –>-->
<!--<!– <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> –>-->
<!--</table>-->
<table schema="" tableName="t_book" domainObjectName="Book"
enableCountByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" enableUpdateByExample="false">
<!-- 忽.略列,不生成bean 字段 -->
<!-- <ignoreColumn column="FRED" /> -->
<!-- 指定列的java数据类型 -->
<!-- <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> -->
</table>
</context>
</generatorConfiguration>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123
然后就可以自动生成代码了
创建包redis
、util
接下来配置redis
缓存与分页插件PageHelper
创建redis配置之类RedisConfig
package com.zking.wxbackgroudprovider.redis;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* redis配置类
* @Configuration -> Beans
* @Bean -> Bean
* @EnableCaching -> 开启注解式缓存
*
**/
@Configuration
@EnableCaching//开启注解式缓存
//继承CachingConfigurerSupport,为了自定义生成KEY的策略。可以不继承。
public class RedisConfig extends CachingConfigurerSupport {
/**
* 生成key的策略 根据类名+方法名+所有参数的值生成唯一的一个key
*
* @return
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
if(obj==null){
continue;
}
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* 管理缓存
*
* @param redisConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//通过Spring提供的RedisCacheConfiguration类,构造一个自己的redis配置类,从该配置类中可以设置一些初始化的缓存命名空间
// 及对应的默认过期时间等属性,再利用RedisCacheManager中的builder.build()的方式生成cacheManager:
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
//CacheManager --> Cache --> Element
//1.CacheManager 缓存管理器对象,获取RedisConnectionFactory
//2.根据Spring提供的RedisCacheConfiguration,获取Cache对象的缓存策略
//3.修改默认的缓存策略
//4.定义缓存对象
//5.给缓存对象设置缓存策略
config = config.entryTtl(Duration.ofMinutes(1)) // 设置缓存的默认过期时间,也是使用Duration设置
.disableCachingNullValues(); // 不缓存空值
// 设置一个初始化的缓存空间set集合
Set<String> cacheNames = new HashSet<>();
cacheNames.add("my-redis-cache1");
cacheNames.add("my-redis-cache2");
// 对每个缓存空间应用不同的配置
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
configMap.put("my-redis-cache1", config);
configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory) // 使用自定义的缓存配置初始化一个cacheManager
.initialCacheNames(cacheNames) // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
.withInitialCacheConfigurations(configMap)
.build();
return cacheManager;
}
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}
分页PageAspect
package com.zking.wxbackgroudprovider.util;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Aspect
public class PageAspect {
@Around("execution(* *..*Service.*Pager(..))") //规则可以你自己定
public Object invoke(ProceedingJoinPoint args) throws Throwable{
Object[] params = args.getArgs();
PageBean pageBean=null;
for (Object param : params) {
if(param instanceof PageBean){
pageBean=(PageBean) param;
break;
}
}
if(null!=pageBean&&pageBean.isPagination())
PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
Object result = args.proceed(params);
if(null!=pageBean&&pageBean.isPagination()){
List lst=(List)result;
PageInfo pageInfo=new PageInfo(lst);
pageBean.setTotal(pageInfo.getTotal()+"");
}
return result;
}
}
PageBean
package com.zking.wxbackgroudprovider.util;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Map;
public class PageBean implements Serializable {
private static final long serialVersionUID = 2422581023658455731L;
//页码
private int page=1;
//每页显示记录数
private int rows=10;
//总记录数
private int total=0;
//是否分页
private boolean isPagination=true;
//上一次的请求路径
private String url;
//获取所有的请求参数
private Map<String,String[]> map;
public PageBean() {
super();
}
//设置请求参数
public void setRequest(HttpServletRequest req) {
String page=req.getParameter("page");
String rows=req.getParameter("rows");
String pagination=req.getParameter("pagination");
this.setPage(page);
this.setRows(rows);
this.setPagination(pagination);
this.url=req.getContextPath()+req.getServletPath();
this.map=req.getParameterMap();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, String[]> getMap() {
return map;
}
public void setMap(Map<String, String[]> map) {
this.map = map;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public void setPage(String page) {
if(null!=page&&!"".equals(page.trim()))
this.page = Integer.parseInt(page);
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public void setRows(String rows) {
if(null!=rows&&!"".equals(rows.trim()))
this.rows = Integer.parseInt(rows);
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public void setTotal(String total) {
this.total = Integer.parseInt(total);
}
public boolean isPagination() {
return isPagination;
}
public void setPagination(boolean isPagination) {
this.isPagination = isPagination;
}
public void setPagination(String isPagination) {
if(null!=isPagination&&!"".equals(isPagination.trim()))
this.isPagination = Boolean.parseBoolean(isPagination);
}
/**
* 获取分页起始标记位置
* @return
*/
public int getStartIndex() {
//(当前页码-1)*显示记录数
return (this.getPage()-1)*this.rows;
}
/**
* 末页
* @return
*/
public int getMaxPage() {
int totalpage=this.total/this.rows;
if(this.total%this.rows!=0)
totalpage++;
return totalpage;
}
/**
* 下一页
* @return
*/
public int getNextPage() {
int nextPage=this.page+1;
if(this.page>=this.getMaxPage())
nextPage=this.getMaxPage();
return nextPage;
}
/**
* 上一页
* @return
*/
public int getPreivousPage() {
int previousPage=this.page-1;
if(previousPage<1)
previousPage=1;
return previousPage;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", isPagination=" + isPagination
+ "]";
}
}
启动类注解
package com.zking.wxbackgroudprovider;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableEurekaClient
@EnableTransactionManagement //开启事务管理器
@EnableAspectJAutoProxy //开动态代理
@MapperScan("com.zking.wxbackgroudprovider.mapper")
public class WxbackgroudProviderApplication {
public static void main(String[] args) {
SpringApplication.run(WxbackgroudProviderApplication.class, args);
}
}
生产者总体结构:
model
实体类包是没有Book
类的,因为我把它放到公共模块了,下面会说明
双生产者完毕
4)双消费者backgroud-consumer
pom依赖
<?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>com.zking</groupId>
<artifactId>WXBackgroud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wxbackgroud-server-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxbackgroud-server-consumer</name>
<packaging>jar</packaging>
<description>子模块之消费者</description>
</project>
yml配置文件
---
# 端口号
server:
port: 7301
# 服务名称
spring:
profiles: consumer1
application:
name: wxbackgroud-consumer
# 服务注册与发现相关配置
eureka:
client:
# 注册中心地址
serviceUrl:
defaultZone: http://peer1:7101/eureka/,http://peer2:7102/eureka/
#开启熔断器熔断器
feign:
hystrix:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
---
# 端口号
server:
port: 7302
# 服务名称
spring:
profiles: consumer2
application:
name: wxbackgroud-consumer
# 服务注册与发现相关配置
eureka:
client:
# 注册中心地址
serviceUrl:
defaultZone: http://peer1:7101/eureka/,http://peer2:7102/eureka/
feign:
hystrix:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
项目新建包controller'
、service
service
包下新建impl
包
新建controller层中的TestController
类
package com.zking.wxbackgroudconsumer.controller;
import com.zking.wxbackgroudconsumer.service.BookFeignService;
import com.zking.wxbackgroudvo.vo.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/test")
@RestController
public class TestController {
@Autowired
private BookFeignService bookFeignService;
@RequestMapping("/queryBook")
public Book queryBook(@RequestBody Book book){
System.out.println(book);
Book book1 = bookFeignService.queryBook(book);
return book1;
}
}
Feign连接类
package com.zking.wxbackgroudconsumer.service;
import com.zking.wxbackgroudconsumer.service.impl.BookFeignServiceImpl;
import com.zking.wxbackgroudvo.vo.Book;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@Service
@FeignClient(value = "wxbackgroud-provider",fallback = BookFeignServiceImpl.class)
public interface BookFeignService {
@RequestMapping("/book/queryBook")
public Book queryBook(@RequestBody Book book);
}
降级服务类
package com.zking.wxbackgroudconsumer.service.impl;
import com.zking.wxbackgroudconsumer.service.BookFeignService;
import com.zking.wxbackgroudvo.vo.Book;
import org.springframework.stereotype.Component;
@Component
public class BookFeignServiceImpl implements BookFeignService {
@Override
public Book queryBook(Book book) {
return null;
}
}
正在启动类添加注解
package com.zking.wxbackgroudconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class WxbackgroudConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(WxbackgroudConsumerApplication.class, args);
}
}
5)熔断器wxbackgroud-hystrix
pom依赖
<?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>com.zking</groupId>
<artifactId>WXBackgroud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>wxbackgroud-hystrix</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxbackgroud-hystrix</name>
<description>Demo project for Spring Boot</description>
</project>
yml配置文件
server:
port: 7401
spring:
application:
name: wxbackgroud-hystrix
management:
endpoints:
web:
exposure:
include: "*"
添加启动类注解
package com.zking.wxbackgroudhystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrixDashboard //启用熔断器仪表盘
public class WxbackgroudHystrixApplication {
public static void main(String[] args) {
SpringApplication.run(WxbackgroudHystrixApplication.class, args);
}
}
6)服务网关backgroud-gateway
pom依赖
<?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>com.zking</groupId>
<artifactId>WXBackgroud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>wxbackgroud-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxbackgroud-gateway</name>
<description>子模块之配置网关</description>
<dependencies>
<!-- 不需要添加到父模块 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
</project>
yml配置文件
server:
port: 7501
spring:
application:
name: gateway
## 配置子模块eureka-consumer的路由规则
#zuul:
# routes:
# api-cons:
# path: /cons/**
# serviceId: eureka-consumer
eureka:
client:
serviceUrl:
defaultZone: http://peer1:7101/eureka/,http://peer2:7102/eureka/
启动类注解
package com.zking.wxbackgroudgateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy //开启网关
public class WxbackgroudGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(WxbackgroudGatewayApplication.class, args);
}
}
最后就是公共模块了
7)公共模块wxbackgroud-vo
pom依赖不要继承父模块
<?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.1.9.RELEASE</version>
</parent>
<groupId>com.zking</groupId>
<artifactId>wxbackgroud-vo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxbackgroud-vo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
不需要配置yml
可以看到我把book
类放到这了,
重点:请实现序列化接口
同时你的mapper层映射的xml文件一定要改实体类路径
例如:
启动项目
前提:
启动顺序
先是双注册中心–>服务网关–>双生产者–>双消费者–>熔断器
postman猜测一下
红色框框的是需要注意的地方,因为controller层用的是@RequestBody Book book