Spring的event驱动

举报
S-X-S 发表于 2025/01/09 11:03:01 2025/01/09
【摘要】 1.目录概览 2.发布和监听事件 1.Person.java 被监听的对象package com.sunxiansheng.user.event;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;/** * Description: 自定义的 * @Author sun *...

1.目录概览

CleanShot 2024-07-24 at 14.46.26@2x

2.发布和监听事件

1.Person.java 被监听的对象

package com.sunxiansheng.user.event;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Description: 自定义的
 * @Author sun
 * @Create 2024/7/24 14:27
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private Integer age;

    private String name;

}

2.PersonChangeEvent.java 自定义事件对象

package com.sunxiansheng.user.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

/**
 * Description: 自定义的事件对象
 * @Author sun
 * @Create 2024/7/24 14:29
 * @Version 1.0
 */
@Getter
public class PersonChangeEvent extends ApplicationEvent {

    /**
     * 要观察的对象
     */
    private Person person;

    /**
     * 操作类型
     */
    private String operateType;

    public PersonChangeEvent(Person person, String operateType) {
        super(person);
        this.person = person;
        this.operateType = operateType;
    }

}

3.PersonEventPublisher.java 发布事件

package com.sunxiansheng.user.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Description: 发布事件
 * @Author sun
 * @Create 2024/7/24 14:32
 * @Version 1.0
 */
@Service
@Slf4j
public class PersonEventPublisher {

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 当创建Person对象时发布事件
     * @param person
     */
    public void createPerson(Person person) {
       applicationEventPublisher.publishEvent(new PersonChangeEvent(person, "create"));
    }

    // 其他情况,发布事件

}

4.PersonEventListener.java 监听事件

package com.sunxiansheng.user.event;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * Description: 监听事件
 * @Author sun
 * @Create 2024/7/24 14:35
 * @Version 1.0
 */
@Service
@Slf4j
public class PersonEventListener {

    /**
     * 监听事件的方法
     * @param personChangeEvent
     */
    @TransactionalEventListener(fallbackExecution = true)
    public void listenEvent(PersonChangeEvent personChangeEvent) {
        switch (personChangeEvent.getOperateType()) {
            case "create":
                // 业务逻辑
                log.info("执行Person创建事件:{}", JSON.toJSONString(personChangeEvent.getPerson()));
                break;
            default:
                break;
        }
    }

}

5.测试

1.PersonEventListenerTest.java
package com.sunxiansheng.user.event;

import com.sunxiansheng.user.UserApplicaion;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

import static org.junit.jupiter.api.Assertions.*;

/**
 * Description: 测试发布和监听事件
 * @Author sun
 * @Create 2024/7/24 14:40
 * @Version 1.0
 */
// 指定项目启动类,并指定随机端口启动,防止与其他的东西冲突
@SpringBootTest(classes = UserApplicaion.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// 规定配置
@RunWith(SpringRunner.class)
@Slf4j
class PersonEventListenerTest {

    @Resource
    private PersonEventPublisher personEventPublisher;

    @Test
    void listenEvent() {
        personEventPublisher.createPerson(new Person(1, "sun"));
    }
}
2.结果

CleanShot 2024-07-24 at 14.50.56@2x

3.异步发布和监听事件

1.Person.java 不变

package com.sunxiansheng.user.event;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Description: 自定义的
 * @Author sun
 * @Create 2024/7/24 14:27
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private Integer age;

    private String name;

}

2.PersonChangeEvent.java 不变

package com.sunxiansheng.user.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

/**
 * Description: 自定义的事件对象
 * @Author sun
 * @Create 2024/7/24 14:29
 * @Version 1.0
 */
@Getter
public class PersonChangeEvent extends ApplicationEvent {

    /**
     * 要观察的对象
     */
    private Person person;

    /**
     * 操作类型
     */
    private String operateType;

    public PersonChangeEvent(Person person, String operateType) {
        super(person);
        this.person = person;
        this.operateType = operateType;
    }

}

3.AsyncConfig.java 配置异步线程池+开启异步事件

package com.sunxiansheng.user.event.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
/**
 * 配置异步线程池+开启异步事件
 */
@Configuration
// 开启异步事件
@EnableAsync
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

4.PersonEventPublisher.java 不变

package com.sunxiansheng.user.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Description: 发布事件
 * @Author sun
 * @Create 2024/7/24 14:32
 * @Version 1.0
 */
@Service
@Slf4j
public class PersonEventPublisher {

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 当创建Person对象时发布事件
     * @param person
     */
    public void createPerson(Person person) {
       applicationEventPublisher.publishEvent(new PersonChangeEvent(person, "create"));
    }

    // 其他情况,发布事件

}

5.PersonEventListener.java 使用自定义线程池进行异步处理

package com.sunxiansheng.user.event;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * Description: 监听事件
 * @Author sun
 * @Create 2024/7/24 14:35
 * @Version 1.0
 */
@Service
@Slf4j
public class PersonEventListener {

    /**
     * 监听事件的方法
     * @param personChangeEvent
     */
    @Async("taskExecutor")
    @TransactionalEventListener(fallbackExecution = true)
    public void listenEvent(PersonChangeEvent personChangeEvent) {
        switch (personChangeEvent.getOperateType()) {
            case "create":
                // 业务逻辑
                log.info("执行Person创建事件:{},处理的线程:{}", JSON.toJSONString(personChangeEvent.getPerson()),
                        Thread.currentThread().getName());
                break;
            default:
                break;
        }
    }

}

6.测试结果

CleanShot 2024-07-24 at 15.04.55@2x

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。