1. 程式人生 > >Spring的事件和監聽器-同步與非同步

Spring的事件和監聽器-同步與非同步

Application下抽象子類ApplicationContextEvent的下面有4個已經實現好的事件 

  1. ContextClosedEvent(容器關閉時) 
  2. ContextRefreshedEvent(容器重新整理是) 
  3. ContextStartedEvent(容器啟動時候) 
  4. ContextStoppedEvent(容器停止的時候) 

同樣,這四個事件都繼承了ApplicationEvent,如果我們想自定義事件,也可以通過繼承ApplicationEvent來實現

1: 首先新建StartWorkflowEvent.java, 繼承ApplicationEvent抽象類

public class StartWorkflowEvent extends ApplicationEvent {
    //存放構造器送入的值
    private String msg;
    //構造器引數可以隨意設定,這裡為了方便除錯,設定為字串
    public StartWorkflowEvent (String msg) {
        super(msg);
        this.msg=msg;
    }
    //自定義一個方法,這個方法也可以隨意寫,這裡也是測試用
    public void myevent(){
        System.out.println("********My event**************");
        System.out.println(msg);
        System.out.println("*******************************");
    }
}

2:新建一個監聽器StartWorkflowListener.java, 實現ApplicationListener<StartWorkflowEvent>

/**
 * 發起流程事件監聽
 */
@Component("startWorkflowListener")
public class StartWorkflowListener implements ApplicationListener<StartWorkflowEvent> {

    @Autowired
    private OaWorkflowHepler oaWorkflowHepler;
	
//@Async註解非同步呼叫時使用, 非同步呼叫時, 需要在xml配置檔案中新增 <task:annotation-driven />
//  @Async
    @Override
    public void onApplicationEvent(StartWorkflowEvent event) {
        oaWorkflowHepler.start(event.getMsg());
    }
}


3:建立一個事件釋出類EventPublisher.java

/**
 * 釋出事件
 */
@Component("eventPublisher")
public class EventPublisher {

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 釋出事件
     * @param event
     */
    public void publishEvent(ApplicationEvent event) {
        applicationContext.publishEvent(event);
    }
}

4.相關的配置:
<task:annotation-driven />配置:
executor:指定一個預設的executor給@Async使用。
例子:
<task:annotation-driven executor="asyncExecutor" />


<task:executor />配置引數:
id:當配置多個executor時,被@Async("id")指定使用;也被作為執行緒名的字首。
pool-size:
core size:最小的執行緒數,預設:1
max size:最大的執行緒數,預設:Integer.MAX_VALUE
queue-capacity:當最小的執行緒數已經被佔用滿後,新的任務會被放進queue裡面,當這個 queue的capacity也被佔滿之後,pool裡面會建立新執行緒處理這個任務,直到匯流排程數達到了max size,這時系統會拒絕這個任務並丟擲TaskRejectedException異常(預設配置的情況下,可以通過rejection-policy 來決定如何處理這種情況)。預設值為:Integer.MAX_VALUE
keep-alive:超過core size的那些執行緒,任務完成後,再經過這個時長(秒)會被結束掉
rejection-policy:當pool已經達到max size的時候,如何處理新任務
ABORT(預設):丟擲TaskRejectedException異常,然後不執行
DISCARD:不執行,也不丟擲異常
DISCARD_OLDEST:丟棄queue中最舊的那個任務
18CALLER_RUNS:不在新執行緒中執行任務,而是有呼叫者所在的執行緒來執行