Spring的事件驱动模型

作用

在传统企业级Spring应用系统中,正是通过事件驱动模型实现信息的异步通信和业务模块的解耦

组成

包括发送消息的生产者、消息(或事件)和监听接收消息的消费者,这三者是绑定在一起的,可以说是“形影不离”

实现步骤(案例)

(1)需要创建用户登录成功后的事件实体类 LoginEvent,该实体类需要继承ApplicationEvent并实现序列化机制

        //导入包
        import lombok.Data;
        import lombok.ToString;
        import org.springframework.context.ApplicationEvent;
        import java.io.Serializable;
        /**
         * 用户登录成功后的事件实体
         * @Author:debug (SteadyJack)
         **/
        @Data
        @ToString
        public class LoginEvent extends ApplicationEvent implements Serializable{
            private String userName;              //用户名
            private String loginTime;             //登录时间
            private String ip; //所在IP
            //构造方法一
            public LoginEvent(Object source) {
              super(source);
            }
            //构造方法二:这是在继承ApplicationEvent类时需要重写的构造方法
            public LoginEvent(Object source, String userName, String loginTime,
        String ip) {
                super(source);
                this.userName = userName;
                this.loginTime = loginTime;
                this.ip = ip;
            }
        }

(2)开发监听消息的消费者Consumer类,该类需要实现ApplicationListener接口并绑定事件源LoginEvent

        //导入包
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.context.ApplicationListener;
        import org.springframework.scheduling.annotation.Async;
        import org.springframework.scheduling.annotation.EnableAsync;
        import org.springframework.stereotype.Component;
        /**Spring的事件驱动模型-消费者
         * @Author:debug (SteadyJack)
        **/
        @Component  //加入Spring的IOC容器
        @EnableAsync //允许异步执行
        public class Consumer implements ApplicationListener<LoginEvent>{
            //定义日志
            private static final Logger log= LoggerFactory.getLogger(Consumer.
        class);
            /**
            * 监听消费消息
            * @param loginEvent
            */
            @Override
            @Async
        public void onApplicationEvent(LoginEvent loginEvent) {
          //打印日志信息
              log.info("Spring事件驱动模型-接收消息:{}", loginEvent);
              //TODO:后续为实现自身的业务逻辑-比如写入数据库等
            }
        }

(3)开发用于发送消息或产生事件的生产者 Producer,通过 Spring内置的ApplicationEventPublisher组件实现消息的发送

        //导入包
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.ApplicationEventPublisher;
        import org.springframework.stereotype.Component;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        /**Spring的事件驱动模型-生产者
         * @Author:debug (SteadyJack)
        **/
        @Component
        public class Publisher {
            //定义日志
            private static final Logger log= LoggerFactory.getLogger(Publisher.
        class);
            //定义发送消息的组件
            @Autowired
            private ApplicationEventPublisher publisher;
            //发送消息的方法
        public void sendMsg() throws Exception{
            //构造 登录成功后用户的实体信息
              LoginEvent event=new LoginEvent(this, "debug", new SimpleDateFormat
        ("yyyyy-MM-dd HH:mm:ss").format(new Date()), "127.0.0.1");
            //发送消息
        publisher.publishEvent(event);
              log.info("Spring事件驱动模型-发送消息:{}", event);
            }
        }

(4)测试方法

        //导入包
        import com.debug.middleware.server.MainApplication;
        import com.debug.middleware.server.event.Publisher;
        import org.junit.Test;
        import org.junit.runner.RunWith;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.test.context.SpringBootTest;
        import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
        /**定义Java单元测试类
         * @Author:debug (SteadyJack)
        **/
        @RunWith(SpringJUnit4ClassRunner.class)
        @SpringBootTest
        public class EventTest {
            //自动装配生产者实例
            @Autowired
            private Publisher publisher;
            //Java单元测试方法
            @Test
        public void test1() throws Exception{
            //调用发送消息的方法产生消息
              publisher.sendMsg();
            }
        }
posted @ 2023-06-03 09:55  紫川先生  阅读(125)  评论(0)    收藏  举报