ApplicationEvent事件驱动设计

使用场景

我这边推荐你的场景是异步的方式来做。
比方你要进行登录,如果你登录了还需要发送邮件,比方你确定你只会做这一个事情而且以后不会增加了,那你就不需要基于事件去做,你可以写一个异步线程。
但是如果你的登录需要做很多事情,比方发送邮件,微信通知,发送短信等等,并且以后你还会增加,那么这时候比较推荐的是使用event事件来做,因为他非常方便以后的扩展。

推荐

推荐使用补充哪里的代码,少些一个类

定义事件(该类不需要写)

package com.jm.test.applicationEvent;

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

public class ActionEvent extends ApplicationEvent {

    @Getter
    private String msg;

    public ActionEvent(Object source,String msg) {
        super(source);
        this.msg = msg;
        System.out.println("action event created");
    }
}

定义发布者

package com.jm.test.applicationEvent.publicsher;

import com.jm.test.applicationEvent.ActionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

@Component
public class ActionPublisher {

    @Autowired
    private ApplicationEventPublisher publisher;

    public void publish(String msg){
        publisher.publishEvent(new ActionEvent(this,msg));
    }
}

定义监听者

通过@order注解,来觉得优先级

package com.jm.test.applicationEvent.listener;

import com.jm.test.applicationEvent.ActionEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
public class ActionListener    {

    @Order(2)
    @EventListener
    public void showAction(ActionEvent actionEvent){
        String msg = actionEvent.getMsg();
        System.out.println("监听者1:"+msg);
        System.out.println("监听者线程="+Thread.currentThread().getId());
    }

    
    @Order(1)
    @EventListener(ActionEvent.class)
    public void showAction2(ActionEvent actionEvent){
        String msg = actionEvent.getMsg();
        System.out.println("监听者2:"+msg);
        System.out.println("监听者线程="+Thread.currentThread().getId());
    }
}

异步监听

听过异步注解,来设置异步的方式监听,但此时@Order的注解就会失效了,因为异步了,就没有优先级了

package com.jm.test.applicationEvent.listener;

import com.jm.test.applicationEvent.ActionEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

@Component
@EnableAsync
public class ActionListener    {

    @Order(2)
    @Async
    @EventListener
    public void showAction(ActionEvent actionEvent){
        String msg = actionEvent.getMsg();
        System.out.println("监听者1:"+msg);
        System.out.println("监听者线程="+Thread.currentThread().getId());
    }


    @Order(1)
    @Async
    @EventListener(ActionEvent.class)
    public void showAction2(ActionEvent actionEvent){
        String msg = actionEvent.getMsg();
        System.out.println("监听者2:"+msg);
        System.out.println("监听者线程="+Thread.currentThread().getId());
    }
}

测试

package com.jm.test.applicationEvent;

import com.jm.test.applicationEvent.publicsher.ActionPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ActionEventController {

    @Autowired
    private ActionPublisher actionPublisher;

    @GetMapping("/testActionEvent")
    public void testActionEvent(){
         actionPublisher.publish("打篮球");
        System.out.println("发送者线程="+Thread.currentThread().getId());
    }
}

方式二 补充(不需要event)

1.1 监听的时间消息

package com.jm.event;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class EventMsg {

    private Long id;
    private String name;
}

1.2 推送消息

package com.jm.event;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Jeremy
 */
@RestController
public class EventPublisher {
    @Autowired
    private ApplicationEventPublisher publisher;

    @GetMapping("/event/publisher")
    public void publisher(){
       // publisher.publishEvent(new MyEvent(this,new EventMsg(1L,"123")));
        System.out.println(Thread.currentThread().getName());
        publisher.publishEvent(new EventMsg(1L,"123"));
    }
}

1.3 监听消息

package com.jm.event;

import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

@Component
@EnableAsync
public class MyEventListener {


    @EventListener(EventMsg.class)
    public void evnetListener(EventMsg event){

        System.out.println(Thread.currentThread().getName());
        System.out.println(event);
    }

    @EventListener(EventMsg.class)
    @Async
    public void evnetListener1(EventMsg event){

        System.out.println(Thread.currentThread().getName());
        System.out.println(event);
    }
}

三. 实战(推荐)

3.1 定义登录事件

package com.jm.event;

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

/**
 * 登录事件
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginEvent {

    private String username;

    private String address;
}

3.2 推送事件

package com.jm.event;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Jeremy
 */
@RestController
public class EventPublisher {
    @Autowired
    private ApplicationEventPublisher publisher;

    @GetMapping("/event/login")
    public void login(){
       // publisher.publishEvent(new MyEvent(this,new EventMsg(1L,"123")));
        System.out.println(Thread.currentThread().getName());
       // publisher.publishEvent(new EventMsg(1L,"123"));
        publisher.publishEvent(new LoginEvent("张三","上海"));
        System.out.println(11234);
    }
}

3.3 监听事件

如果以后登录还需要进行,其他的操作或者进行登录业务的补充。
只要在这个里面添加一个监听。

package com.jm.event;

import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

@Component
@EnableAsync
public class MyEventListener {


    /**
     * 登录进行邮件发送
     * @param event
     */
    @EventListener(LoginEvent.class)
    @Async
    public void sendEmail(LoginEvent event){
        System.out.println(Thread.currentThread().getName()+"=发送邮件+"+event);
    }

    /**
     * 登录进行微信通知
     * @param event
     */
    @EventListener(LoginEvent.class)
    @Async
    public void sendWeChat(LoginEvent event){
        System.out.println(Thread.currentThread().getName()+"=微信通知+"+event);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值