Spring中使用ApplicationEvent机制,实际项目开发使用

本文介绍了如何在Spring中使用事件驱动进行账号注册后的同步操作。通过定义自定义事件、创建监听器并发布事件,实现了账号信息在注册完成后同步到权限平台的功能。示例中展示了使用ApplicationListener接口和@EventListener注解两种监听方式,以及封装ApplicationContext的事件发布方法。
摘要由CSDN通过智能技术生成

Spring中使用事件非常简单,只需要以下的几个步骤:

  • 1.定义事件,继承ApplicationEvent
  • 2.定义监听,要么实现ApplicationListener接口,要么在方法上添加@EventListener注解
  • 3.定义发布事件借口,调用ApplicationContext.publishEvent()或者ApplicationEventPublisher.publishEvent();
  • 4.业务调用发布事件

业务场景: 注册账号完成之后,需要将账号信息同步到权限平台。
————————————————————————————————————————————————————————————

1.首先定义一个事件(Event)

1.1实际项目:

@Data
public class BaseAsgardEvent<T> extends ApplicationEvent {
    private T data;

    public BaseAsgardEvent(Object source) {
        super(source);
    }

    public BaseAsgardEvent(Object source,T data){
        super(source);
        this.data = data;
    }
}

1.2参考别人文档:

//自定义事件需要继承ApplicationEvent
public class UserRegisterEvent extends ApplicationEvent {
    private String username;
    public UserRegisterEvent(Object source, String username) {
        super(source);
        this.username = username;
    }
    public String getUsername() {
        return username;
    }
}

2.定义一个事件监听器(Listener)

2.1 定义事件监听器两种方式

//可以实现ApplicationListener接口监听事件
@Component
@Order(2)//可以使用order指定顺序,越小优先级越高
public class MailUserRegisterListener implements ApplicationListener<UserRegisterEvent> {
    @Override
    public void onApplicationEvent(UserRegisterEvent event) {
        System.out.println(Thread.currentThread().getName()+"-给用户"+event.getUsername()+"发送邮件!");
    }
}
//也可以使用@EventListener监听事件
@Component
@Order(1)
public class CouponUserRegisterListener {
    @EventListener
    public void sendCoupon(UserRegisterEvent event) {
        System.out.println(Thread.currentThread().getName()+"-给用户"+event.getUsername()+"发送优惠券!");
    }
}

2.2 实际项目:

@Component
@Slf4j
public class AccountEventListener {

    @Autowired
    UniformAccessClient uniformAccessClient;
    @Autowired
    AccountMapper accountMapper;


    @EventListener
    public void merchantBusinessRecordEventListener(BaseAsgardEvent<Account> event) {

        Account account = event.getData();
        try {
            if (account == null) {
                return;
            }
            AccountPO accountPO = accountMapper.selectByPrimaryKey(account.getId());
            //调用权限平台服务,同步信息
            uniformAccessClient.syncAccountToUniformAccessClient(accountPO);
        } catch (Exception e) {
            log.error("商户档案变更,同步发送消息失败", e);
        }
    }


}

3.发布事件方法,这里包装ApplicationContext方法使用

@Component
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    /**
     * 获取静态变量中的ApplicationContext.
     */
    public static ApplicationContext getApplicationContext() {
        assertContextInjected();
        return applicationContext;
    }

    /**
     * 从静态变量applicationContext中得到Bean, 自动转型为所赋值对象的类型.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        assertContextInjected();
        return (T) applicationContext.getBean(name);
    }

    /**
     * 从静态变量applicationContext中得到Bean, 自动转型为所赋值对象的类型.
     */
    public static <T> T getBean(Class<T> requiredType) {
        assertContextInjected();
        return applicationContext.getBean(requiredType);
    }

    /**
     * 清除SpringContextHolder中的ApplicationContext为Null.
     */
    public static void clearHolder() {
        applicationContext = null;
    }

    /**
     * 实现ApplicationContextAware接口, 注入Context到静态变量中.
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.applicationContext = applicationContext;
    }

    /**
     * 检查ApplicationContext不为空.
     */
    private static void assertContextInjected() {
        Validate.validState(applicationContext != null,
                "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
    }


    //包装方法
    public static void publish(Object event) {
        applicationContext.publishEvent(event);
    }



}

4.实际使用:

@Service
public class TestMethod {


    
    public void store(Account account) {
    //处理账号业务。。。。。。。。。。。
    //处理其他业务完成。。。。。。。。。。。

        //商户账号 同步
        BaseAsgardEvent<Account> event = new BaseAsgardEvent<Account>("ACCOUNT", account);
        SpringContextHolder.publish(event);

    }
    }
TApplication.OnIdle   当应用程序变为空闲时,OnIdle事件发生。   使用OnIdle事件,可以写一个应用程序空闲时执行特定处理的事件处理程序。当应用程序不处理代码时,称为应用程序空闲。例如,当应用程序等待来自用户的输入时,应用程序为空闲。   TIdleEvent类型是OnIdle事件的类型,它指向一个应用程序空闲时运行的方法。TIdleEvent类型有一个布尔型参数Done,默认时该参数为True。若参数Done为True,当OnIdle事件返回时,调用Windows API WaitMessage函数。只有在应用程序消息队列出现一个新消息时,WaitMessage函数才放弃对其他应用程序的控制。参数Done为False时,即使应用程序不忙,也不放弃对其他应用程序的控制。   当应用程序转移到空闲状态时,只调用一次OnIdle事件。除非参数Done设置为False,否则不连续调用OnIdle事件。将参数Done设置为False的应用程序,将消耗过多的CPU时间,从而影响整个系统性能。 在delphi, 当在一个窗口上放置一个ApplicationEvents控件时,Application将会把所有的事件都转寄到ApplicationEvents; 也就是说,ApplicationEvents可以拦截到应用程序的全部事件,包括OnActivate\OnHelp\OnIdle\OnRestore\OnShortCut等等, 甚至可能通过OnMessage事件,在其截取所有post到应用程序所有窗口的消息,如WM_PAINT,WM_KEYDOWN, WM_KEYUP等常见的windows消息; 所以当有消息到来的时候就会触发它的OnMessage事件,在OnMessage监视消息就可以了。 Action的事件有OnExecute和OnUpdate,OnExecute事件在控制被触发时响应,比如说按钮被按下,菜单被按下,而OnUpdate事件是在应用程序空闲时被调用, APPLICATIONEVENTS是用来捕获程序级事件的 ApplicationEvents1Message(var Msg: tagMSG;var Handled: Boolean); {通过 Perform 向窗体发送 消息; OnMessage 收不到} {通过 SendMessage 向窗体发送 消息; OnMessage 收不到} {通过 PostMessage 向窗体发送  消息; OnMessage 可以收到}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值