Spring event应用

当我们在实现某些特定业务逻辑时,通常会通过发送事件的方式实现代码解耦,这也是观察者模式的一种体现。从spring 3.0.5为我们实现了用annotation实现event和eventListner。
一个事件包含:事件发布、监听、和事件源。在spring中我们可以通过ApplicationContext的publishEvent方法去发布事件;通过实现实现ApplicationListener接口来自定义自己的监听器;继承ApplicationEvent类来实现事件源。下面以一个实例来说明:
定义一个事件A事件源:

package cn.slimsmart.spring.demo.event;

import org.springframework.context.ApplicationEvent;

//A事件
public class AEvent extends ApplicationEvent{

    private static final long serialVersionUID = 1L;

    private String name = "AAAA";
    public String getName() {
        return name;
    }

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

监听事件A:

@Component
public class AEventListener implements ApplicationListener{

    public void onApplicationEvent(ApplicationEvent event) {
        System.err.println(this.getClass().getName());
        if(event instanceof AEvent){
            //处理事件A业务逻辑
        }
        System.out.println(event.getSource());
    }
}

发布事件:

applicationContext.publishEvent(new AEvent("testA"));

从上面的监听器处理可以看出,需要通过event instanceof AEvent判断事件源来处理对于的业务逻辑,这样很不爽,当然有更好的方式。接口ApplicationListener支持泛型,可以通过泛型来判断处理的事件源。如下只处理BEvent源。

@Component
public class BEventListener implements ApplicationListener<BEvent>{

    public void onApplicationEvent(BEvent bEvent) {
        System.out.println("event name : "+bEvent.getName());
        System.out.println(bEvent.getSource());
    }
}

如果事件没要处理的监听器,就会被抛弃。
以上处理事件都是同步的,如果发布事件处的业务存在事务,监听器处理也会在相同的事务下。
如果是发送邮箱、短信等耗时操作,如何让事件异步处理呢?
1、全局异步配置


    <task:executor id="executor" pool-size="3" queue-capacity="20" />
    
    
    
    <bean id="applicationEventMulticaster"
        class="org.springframework.context.event.SimpleApplicationEventMulticaster">
        
        <property name="taskExecutor" ref="executor" />
    bean>

通过注入taskExecutor来完成异步事件调用。不推荐全局配置。
2、@Aync注解来完成异步调用
spring3提供了@Aync注解来完成异步调用。不仅支持异步调用,还支持简单的任务调度。

    
    <aop:aspectj-autoproxy proxy-target-class="true" />
    
    <task:scheduler id="scheduler" pool-size="10" />
    
    <task:executor id="executor" pool-size="10" />
    
    <task:annotation-driven executor="executor" proxy-target-class="true"  scheduler="scheduler"  />

如上配置,在任何方法增加@Aync注解都会异步执行,通过executor完成异步处理。通过方法增加@Scheduled注解完成任务调度。
对于事件的处理可以onApplicationEvent方法上加@Aync支持异步。
@Aync注解的应用范围:
类:表示这个类中的所有方法都是异步的
方法:表示这个方法是异步的,如果类也注解了,则以这个方法的注解为准
上面的配置可以简化只配置:默认会有缺省的executor。
注:在spring boot 开启异步配置在配置类中添加注解@EnableAsync 。

你可能感兴趣的:(Spring)