Spring 异步事件

Spring提供了事件机制,实现了观察者模式,可以让事件发布者和事件监听者解耦,事件发布者可以发布时间而不需要知道谁会监听,如果实现了异步事件还不会影响主流业务逻辑。

Spring的事件机制,最常用在系统状态监测,系统日志等不影响主线业务的逻辑处理。

例子:

登录事件

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.springframework.context.ApplicationEvent;

public class LoginEvent  extends ApplicationEvent {
    private static final long serialVersionUID = 7574015506926006629L;

    private final Map<String, Object> params = new HashMap<String, Object>();

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

    public void addParam(String key, Object value) {
        this.params.put(key, value);
    }

    public Map<String, Object> getParams() {
        return Collections.unmodifiableMap(params);
    }
}

登录处理类,例如将登录人数加1

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class LoginCounterHandler implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent arg0) {
        if (arg0 instanceof LoginEvent) {
            // TODO refresh login count
            System.out.println("a user login to system");
        }
    }
}
 

发布事件

LoginEvent event = new LoginEvent(this);
event.addParam("name", "foo");
ApplicationContextProvider.getApplicationContext().publishEvent(event);
 

为了实现异步事件处理,这里需要重新实现SimpleApplicationEventMulticaster

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.task.TaskExecutor;

public class AsyncApplicationEventMulticaster extends SimpleApplicationEventMulticaster {
	private TaskExecutor taskExecutor = new TaskExecutor() {
		ExecutorService exeserv = Executors.newCachedThreadPool();
		public void execute(Runnable task) {
			exeserv.execute(task);
		}
	};

	protected TaskExecutor getTaskExecutor() {
		return this.taskExecutor;
	}
}
 

另外为了容易获取applicationContext,加了一个ApplicationContextProvider

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextProvider implements ApplicationContextAware {
	private static ApplicationContext ctx = null;

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		ctx = applicationContext;
	}

	public static ApplicationContext getApplicationContext() {
		return ctx;
	}
}

bean配置

    <bean name="applicationEventMulticaster" class="org.jamie.domo.spring.context.AsyncApplicationEventMulticaster" ></bean>
    <bean id="applicationContextProvider" class="org.jamie.domo.spring.context.ApplicationContextProvider"></bean>
    <bean name="loginCounterHandler" class="org.jamie.domo.spring.context.LoginCounterHandler"></bean>
 

总结:真是要感谢Spring提供了很多现成的模式让我们的系统更加的松耦合,给我们带来了很多便利。

猜你喜欢

转载自jamie-wang.iteye.com/blog/1708716