Browse Source

Spring事件驱动模式实现业务解耦

pull/2/head
马府强 2 years ago
parent
commit
520567a100
  1. 27
      springeventqudong/.gitignore
  2. 92
      springeventqudong/fanfu-web.iml
  3. 136
      springeventqudong/pom.xml
  4. 16
      springeventqudong/src/main/java/com/woniu/WoNiuApplication.java
  5. 48
      springeventqudong/src/main/java/com/woniu/service/controller/TestController.java
  6. 63
      springeventqudong/src/main/java/com/woniu/service/event/BizEvent.java
  7. 25
      springeventqudong/src/main/java/com/woniu/service/event/BizEventListener.java
  8. 22
      springeventqudong/src/main/java/com/woniu/service/event/CouponsHandlerListener.java
  9. 15
      springeventqudong/src/main/java/com/woniu/service/event/EventEngine.java
  10. 44
      springeventqudong/src/main/java/com/woniu/service/event/EventEngineConfig.java
  11. 76
      springeventqudong/src/main/java/com/woniu/service/event/EventEngineImpl.java
  12. 23
      springeventqudong/src/main/java/com/woniu/service/event/EventEngineTopic.java
  13. 32
      springeventqudong/src/main/java/com/woniu/service/event/EventSubscriber.java
  14. 20
      springeventqudong/src/main/java/com/woniu/service/event/MembershipHandlerListener.java
  15. 22
      springeventqudong/src/main/java/com/woniu/service/event/MsgHandlerListener.java
  16. 16
      springeventqudong/src/main/java/com/woniu/service/ipregion/Ip.java
  17. 34
      springeventqudong/src/main/java/com/woniu/service/ipregion/IpAspect.java
  18. 31
      springeventqudong/src/main/java/com/woniu/service/util/AddressUtil.java
  19. 28
      springeventqudong/src/main/java/com/woniu/service/util/HttpContextUtil.java
  20. 37
      springeventqudong/src/main/java/com/woniu/service/util/IPUtil.java
  21. 124
      springeventqudong/woniu-web.iml

27
springeventqudong/.gitignore

@ -0,0 +1,27 @@
# Created by .ignore support plugin (hsz.mobi)
### Java template
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/.idea/
/target/

92
springeventqudong/fanfu-web.iml

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
<sourceRoots>
<root url="file://$MODULE_DIR$/src/main/java" />
<root url="file://$MODULE_DIR$/src/main/resources" />
</sourceRoots>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.26" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.11.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.43" level="project" />
<orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.43" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.13.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.3.9.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.3.9.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.3.9.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.16.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.vintage:junit-vintage-engine:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.10.20" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.20" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.2.13.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
</component>
</module>

136
springeventqudong/pom.xml

@ -0,0 +1,136 @@
<?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.ayi</groupId>
<artifactId>woniu-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>woniou-web</name>
<description>create by woniu</description>
<packaging>jar</packaging>
<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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.0-jre</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<!-- swagger 因为mybatisPlus代码生成器会自带swagger的注解 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<!-- 启动后加载配置文件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- lombok 简化实体类管理工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- fastjson 解析json用到,也可以换成自己喜欢用的 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- aop切面 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<!-- ip2region -->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.3</version>
</dependency>
<!-- 用于读取ip2region.xdb文件使用 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

16
springeventqudong/src/main/java/com/woniu/WoNiuApplication.java

@ -0,0 +1,16 @@
package com.woniu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WoNiuApplication {
public static void main(String[] args) {
SpringApplication.run(WoNiuApplication.class, args);
}
}

48
springeventqudong/src/main/java/com/woniu/service/controller/TestController.java

@ -0,0 +1,48 @@
package com.woniu.service.controller;
import com.woniu.service.event.BizEvent;
import com.woniu.service.event.EventEngine;
import com.woniu.service.event.EventEngineTopic;
import com.woniu.service.ipregion.Ip;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 基于Spring事件驱动模式实现业务解耦
*/
@RestController
@RequestMapping("/test")
public class TestController {
@Resource(name = "eventEngineJob")
private EventEngine eventEngine;
@GetMapping("/doRegisterVip")
public String doRegisterVip(@RequestParam(required = true) String userName,
@RequestParam(required = true) Integer age) {
Map<String, Object> paramMap = new HashMap<>(16);
paramMap.put("userName", userName);
paramMap.put("age", age);
//1、注册会员,这里不实现了
System.out.println("注册会员成功");
//2、入会员群
eventEngine.publishEvent(
new BizEvent(EventEngineTopic.JOIN_MEMBERSHIP_GROUP, UUID.randomUUID().toString(), paramMap));
//3、发优惠券
eventEngine.publishEvent(
new BizEvent(EventEngineTopic.ISSUE_COUPONS, UUID.randomUUID().toString(), paramMap));
//4、推送消息
eventEngine.publishEvent(
new BizEvent(EventEngineTopic.SEND_WELCOME_MSG, UUID.randomUUID().toString(), paramMap));
return "注册会员成功";
}
}

63
springeventqudong/src/main/java/com/woniu/service/event/BizEvent.java

@ -0,0 +1,63 @@
package com.woniu.service.event;
import java.util.EventObject;
/**
* 业务事件
*/
public class BizEvent extends EventObject {
/**
* Topic
*/
private final String topic;
/**
* 业务id
*/
private final String bizId;
/**
* 数据
*/
private final Object data;
/**
* @param topic 事件topic用于区分事件类型
* @param bizId 业务ID标识这一次的调用
* @param data 事件传输对象
*/
public BizEvent(String topic, String bizId, Object data) {
super(data);
this.topic = topic;
this.bizId = bizId;
this.data = data;
}
/**
* Getter method for property <tt>topic</tt>.
*
* @return property value of topic
*/
public String getTopic() {
return topic;
}
/**
* Getter method for property <tt>id</tt>.
*
* @return property value of id
*/
public String getBizId() {
return bizId;
}
/**
* Getter method for property <tt>data</tt>.
*
* @return property value of data
*/
public Object getData() {
return data;
}
}

25
springeventqudong/src/main/java/com/woniu/service/event/BizEventListener.java

@ -0,0 +1,25 @@
package com.woniu.service.event;
import java.util.EventListener;
/**
* 业务事件监听器
*/
public interface BizEventListener extends EventListener {
/**
* 是否执行事件
*
* @param event 事件
* @return
*/
public boolean decide(BizEvent event);
/**
* 执行事件
*
* @param event 事件
*/
public void onEvent(BizEvent event);
}

22
springeventqudong/src/main/java/com/woniu/service/event/CouponsHandlerListener.java

@ -0,0 +1,22 @@
package com.woniu.service.event;
import org.springframework.stereotype.Component;
/**
* 优惠券处理器
*/
@Component
public class CouponsHandlerListener implements BizEventListener {
@Override
public boolean decide(BizEvent event) {
return true;
}
@Override
public void onEvent(BizEvent event) {
System.out.println("优惠券处理器:十折优惠券已发放");
}
}

15
springeventqudong/src/main/java/com/woniu/service/event/EventEngine.java

@ -0,0 +1,15 @@
package com.woniu.service.event;
/**
* @className: EventEngine
* @author: woniu
* @date: 2023/4/8
**/
public interface EventEngine {
/**
* 发送事件
*
* @param event 事件
*/
void publishEvent(BizEvent event);
}

44
springeventqudong/src/main/java/com/woniu/service/event/EventEngineConfig.java

@ -0,0 +1,44 @@
package com.woniu.service.event;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class EventEngineConfig {
/**
* 线程池异步处理事件
*/
private static final Executor EXECUTOR = new ThreadPoolExecutor(20, 50, 10, TimeUnit.MINUTES,
new LinkedBlockingQueue(500), new CustomizableThreadFactory("EVENT_ENGINE_POOL"));
@Bean("eventEngineJob")
public EventEngine initJobEngine(CouponsHandlerListener couponsHandlerListener,
MembershipHandlerListener membershipHandlerListener,
MsgHandlerListener msgHandlerListener) {
Map<String, List<BizEventListener>> bizEvenListenerMap = new HashMap<>();
//注册优惠券事件
bizEvenListenerMap.put(EventEngineTopic.ISSUE_COUPONS, Arrays.asList(couponsHandlerListener));
//注册会员群事件
bizEvenListenerMap.put(EventEngineTopic.JOIN_MEMBERSHIP_GROUP, Arrays.asList(membershipHandlerListener));
//注册消息推送事件
bizEvenListenerMap.put(EventEngineTopic.SEND_WELCOME_MSG, Arrays.asList(msgHandlerListener));
EventEngineImpl eventEngine = new EventEngineImpl();
eventEngine.setBizSubscribers(bizEvenListenerMap);
eventEngine.setAsync(true);
eventEngine.setBizListenerExecutor(EXECUTOR);
return eventEngine;
}
}

76
springeventqudong/src/main/java/com/woniu/service/event/EventEngineImpl.java

@ -0,0 +1,76 @@
package com.woniu.service.event;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import org.springframework.util.CollectionUtils;
/**
* 事件引擎实现类
*/
public class EventEngineImpl implements EventEngine {
/**
* 异步执行器也系统需要自行定义线程池
*/
private Executor bizListenerExecutor;
/**
* 是否异步默认为false
*/
private boolean async;
/**
* 订阅端 KEY是TOPICVALUES是监听器集合
*/
private Map<String, List<BizEventListener>> bizSubscribers = new HashMap<>(16);
@Override
public void publishEvent(BizEvent event) {
List<BizEventListener> listeners = bizSubscribers.get(event.getTopic());
if (CollectionUtils.isEmpty(listeners)) {
return;
}
for (BizEventListener bizEventListener : listeners) {
if (bizEventListener.decide(event)) {
//异步执行的话,放入线程池
if (async) {
bizListenerExecutor.execute(new EventSubscriber(bizEventListener, event));
} else {
bizEventListener.onEvent(event);
}
}
}
}
/**
* Setter method for property <tt>bizListenerExecutor</tt>.
*
* @param bizListenerExecutor value to be assigned to property bizListenerExecutor
*/
public void setBizListenerExecutor(Executor bizListenerExecutor) {
this.bizListenerExecutor = bizListenerExecutor;
}
/**
* Setter method for property <tt>bizSubscribers</tt>.
*
* @param bizSubscribers value to be assigned to property bizSubscribers
*/
public void setBizSubscribers(Map<String, List<BizEventListener>> bizSubscribers) {
this.bizSubscribers = bizSubscribers;
}
/**
* Setter method for property <tt>async</tt>.
*
* @param async value to be assigned to property async
*/
public void setAsync(boolean async) {
this.async = async;
}
}

23
springeventqudong/src/main/java/com/woniu/service/event/EventEngineTopic.java

@ -0,0 +1,23 @@
package com.woniu.service.event;
/**
* 事件引擎topic用于区分事件类型
*/
public class EventEngineTopic {
/**
* 入会员群
*/
public static final String JOIN_MEMBERSHIP_GROUP = "joinMembershipGroup";
/**
* 发优惠券
*/
public static final String ISSUE_COUPONS = "issueCoupons";
/**
* 推送消息
*/
public static final String SEND_WELCOME_MSG = "sendWelcomeMsg";
}

32
springeventqudong/src/main/java/com/woniu/service/event/EventSubscriber.java

@ -0,0 +1,32 @@
package com.woniu.service.event;
/**
* 事件监听者注意此时已经没有线程上下文如果需要请修改构造函数显示复制上下文信息
*/
public class EventSubscriber implements Runnable {
/**
* 业务监听器
**/
private BizEventListener bizEventListener;
/**
* 业务事件
*/
private BizEvent bizEvent;
/**
* @param bizEventListener 事件监听者
* @param bizEvent 事件
*/
public EventSubscriber(BizEventListener bizEventListener, BizEvent bizEvent) {
super();
this.bizEventListener = bizEventListener;
this.bizEvent = bizEvent;
}
@Override
public void run() {
bizEventListener.onEvent(bizEvent);
}
}

20
springeventqudong/src/main/java/com/woniu/service/event/MembershipHandlerListener.java

@ -0,0 +1,20 @@
package com.woniu.service.event;
import org.springframework.stereotype.Component;
/**
* 会员群处理器
*/
@Component
public class MembershipHandlerListener implements BizEventListener {
@Override
public boolean decide(BizEvent event) {
return true;
}
@Override
public void onEvent(BizEvent event) {
System.out.println("会员群处理器:您已成功加入会员群");
}
}

22
springeventqudong/src/main/java/com/woniu/service/event/MsgHandlerListener.java

@ -0,0 +1,22 @@
package com.woniu.service.event;
import org.springframework.stereotype.Component;
/**
* 消息推送处理器
*/
@Component
public class MsgHandlerListener implements BizEventListener {
@Override
public boolean decide(BizEvent event) {
return true;
}
@Override
public void onEvent(BizEvent event) {
System.out.println("消息推送处理器:欢迎成为会员!!!");
}
}

16
springeventqudong/src/main/java/com/woniu/service/ipregion/Ip.java

@ -0,0 +1,16 @@
package com.woniu.service.ipregion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @className: Ip
* @author: woniu 公众号程序员蜗牛g
* @date: 2023/4/5
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Ip {
}

34
springeventqudong/src/main/java/com/woniu/service/ipregion/IpAspect.java

@ -0,0 +1,34 @@
package com.woniu.service.ipregion;
import com.woniu.service.util.AddressUtil;
import com.woniu.service.util.HttpContextUtil;
import com.woniu.service.util.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;
@Aspect
@Component
@Slf4j
public class IpAspect {
@Pointcut("@annotation(com.woniu.service.ipregion.Ip)")
public void pointcut() {
}
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
String ip = IPUtil.getIpAddr(request);
log.info(MessageFormat.format("当前IP为:[{0}];当前IP地址解析出来的地址为:[{1}]", ip, AddressUtil.getCityInfo(ip)));
return point.proceed();
}
}

31
springeventqudong/src/main/java/com/woniu/service/util/AddressUtil.java

@ -0,0 +1,31 @@
package com.woniu.service.util;
import org.lionsoul.ip2region.xdb.Searcher;
public class AddressUtil {
/**
* 根据IP地址查询登录来源
*
* @param ip
* @return
*/
public static String getCityInfo(String ip) {
try {
Searcher searcher = Searcher.newWithFileOnly("ip2region/ip2region.xdb");
//开始查询
return searcher.searchByStr(ip);
} catch (Exception e) {
e.printStackTrace();
}
//默认返回空字符串
return "";
}
public static void main(String[] args) {
//204.16.111.255
System.out.println(getCityInfo("204.16.111.255"));
}
}

28
springeventqudong/src/main/java/com/woniu/service/util/HttpContextUtil.java

@ -0,0 +1,28 @@
package com.woniu.service.util;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
/**
* @desc 全局获取HttpServletRequestHttpServletResponse
* 公众号程序员蜗牛g
*/
public class HttpContextUtil {
private HttpContextUtil() {
}
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
public static HttpServletResponse getHttpServletResponse() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
}
}

37
springeventqudong/src/main/java/com/woniu/service/util/IPUtil.java

@ -0,0 +1,37 @@
package com.woniu.service.util;
import javax.servlet.http.HttpServletRequest;
/**
* @desc 查询当前访问的IP地址
*/
public class IPUtil {
private static final String UNKNOWN = "unknown";
protected IPUtil() {
}
/**
* 获取 IP地址
* 使用 Nginx等反向代理软件 则不能通过 request.getRemoteAddr()获取 IP地址
* 如果使用了多级反向代理的话X-Forwarded-For的值并不止一个而是一串IP地址
* X-Forwarded-For中第一个非 unknown的有效IP字符串则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
}

124
springeventqudong/woniu-web.iml

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
<sourceRoots>
<root url="file://$MODULE_DIR$/src/main/java" />
<root url="file://$MODULE_DIR$/src/main/resources" />
</sourceRoots>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.26" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.11.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.43" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.43" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.13.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.13.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.3.9.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.3.9.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.3.9.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.vintage:junit-vintage-engine:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.3.3" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.20" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.20" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.2.13.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.7.0" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:30.0-jre" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
<orderEntry type="library" name="Maven: org.assertj:assertj-core:3.16.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.31" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.13" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.13" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.7.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.7.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.7.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.7.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.1.0.Final" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.3.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.79" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.5" level="project" />
<orderEntry type="library" name="Maven: org.lionsoul:ip2region:2.6.3" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
</component>
</module>
Loading…
Cancel
Save