测试用例
public class SpringEventTest {
@Test
public void test_listener() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
System.out.println("发布事件");
TestEvent event = new TestEvent(new Object(), "事件1");
context.publishEvent(event);
context.close();
}
}
config类
@Configuration
public class EventConfig {
@EventListener
public void listen(TestEvent event) {
System.out.println("接收到事件:" + event);
}
}
TestEvent类
public class TestEvent extends ApplicationEvent {
private String name;
public TestEvent(Object source, String name) {
super(source);
this.name = name;
}
public TestEvent(Object source) {
super(source);
}
@Override
public String toString() {
return "TestEvent{name='" + name + '\'' + '}';
}
}
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}finally {
resetCommonCaches();
}
}
}
其中与EventListener有关联的步骤
原理:通过EventListenerMethodProcessor来处理@Eventlstener标记的方法,将其生成ApplicationListener(ApplicationListenerMethodAdapter)对象。在publishEvent时,通过getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType)函数,获取到ApplicationListener对象,通过反射调用方法。
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware
SmartInitializingSingleton什么时候执行呢
在Refresh()
- finishBeanFactoryInitialization(beanFactory);
- DefaultListableBeanFactory#preInstantiateSingletons:前半部分主要是遍历beanNames 创建Bean。创建完bean后判断各bean是不是SmartInitializingSingleton,如果是则执行 smartSingleton.afterSingletonsInstantiated()方法;
- EventListenerMethodProcessor#afterSingletonsInstantiated;
- EventListenerMethodProcessor#processBean;
- 查找类中标注@EventListener的方法
- EventListenerFactory.createApplicationListener(beanName, targetType, methodToUse) 构造listener
- 添加listener到Context中
- 如果有applicationEventMulticaster,添加到ApplicationContext.applicationEventMulticaster中
- 如果没有applicationEventMulticaster,添加到ApplicationContext.applicationListeners中。
- AbstractApplicationContext#publishEvent
- SimpleApplicationEventMulticaster#multicastEvent
- ApplicationListenerMethodAdapter#onApplicationEvent
protected void processBean(
final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
//没有注解的class
if (!this.nonAnnotatedClasses.contains(targetType)) {
Map<Method, EventListener> annotatedMethods = null;
//查找被注解EventListener的方法
try {
annotatedMethods = MethodIntrospector.selectMethods(targetType,
(MethodIntrospector.MetadataLookup<EventListener>) method ->
AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
}
catch (Throwable ex) {
// An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
}
}
//添加到没有注解的集合
if (CollectionUtils.isEmpty(annotatedMethods)) {
this.nonAnnotatedClasses.add(targetType);
if (logger.isTraceEnabled()) {
logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
}
}
else {
// Non-empty set of methods
ConfigurableApplicationContext context = getApplicationContext();
for (Method method : annotatedMethods.keySet()) {
for (EventListenerFactory factory : factories) {
if (factory.supportsMethod(method)) {
Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
//创建applicationListener,通过Adapter将注解形式的listener转换为普通的listener
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
}
//添加listner到applicationContext
context.addApplicationListener(applicationListener);
break;
}
}
}
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +beanName + "': " + annotatedMethods);
}
}
}
}
@Async
@EventListener
public void listen(TestEvent event) {
System.out.println(Thread.currentThread().getName() + "接收到事件:" + event);
}
@Async
@EventListener("testTaskExecutor")
public void listen(TestEvent event) {
System.out.println(Thread.currentThread().getName() + "接收到事件:" + event);
}
线程池@Configuration
public class TaskPoolConfig {
@Bean("testTaskExecutor")
public Executor sendMessageTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程数:线程池创建时候初始化的线程数
//最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
//缓冲队列:用来缓冲执行任务的队列
//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
//线程池对拒绝任务的处理策略:这里采用了CallerRunsPolicy策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(20);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("testTaskExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}