/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.context.event; import java.util.HashSet; import java.util.Set; import org.aopalliance.intercept.MethodInvocation; import org.easymock.EasyMock; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.TestBean; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.BeanThatBroadcasts; import org.springframework.context.BeanThatListens; import org.springframework.context.support.StaticApplicationContext; import org.springframework.core.Ordered; /** * Unit and integration tests for the ApplicationContext event support. * * @author Alef Arendsen * @author Rick Evans */ public class ApplicationContextEventTests { @Test public void simpleApplicationEventMulticaster() { ApplicationListener listener = EasyMock.createMock(ApplicationListener.class); ApplicationEvent evt = new ContextClosedEvent(new StaticApplicationContext()); listener.onApplicationEvent(evt); SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster(); smc.addApplicationListener(listener); replay(listener); smc.multicastEvent(evt); verify(listener); } @Test public void orderedListeners() { MyOrderedListener1 listener1 = new MyOrderedListener1(); MyOrderedListener2 listener2 = new MyOrderedListener2(listener1); SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster(); smc.addApplicationListener(listener2); smc.addApplicationListener(listener1); smc.multicastEvent(new MyEvent(this)); smc.multicastEvent(new MyOtherEvent(this)); } @Test public void proxiedListeners() { MyOrderedListener1 listener1 = new MyOrderedListener1(); MyOrderedListener2 listener2 = new MyOrderedListener2(listener1); ApplicationListener proxy1 = (ApplicationListener) new ProxyFactory(listener1).getProxy(); ApplicationListener proxy2 = (ApplicationListener) new ProxyFactory(listener2).getProxy(); SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster(); smc.addApplicationListener(proxy1); smc.addApplicationListener(proxy2); smc.multicastEvent(new MyEvent(this)); smc.multicastEvent(new MyOtherEvent(this)); } @Test public void testEventPublicationInterceptor() throws Throwable { MethodInvocation invocation = EasyMock.createMock(MethodInvocation.class); ApplicationContext ctx = EasyMock.createMock(ApplicationContext.class); EventPublicationInterceptor interceptor = new EventPublicationInterceptor(); interceptor.setApplicationEventClass(MyEvent.class); interceptor.setApplicationEventPublisher(ctx); interceptor.afterPropertiesSet(); expect(invocation.proceed()).andReturn(new Object()); expect(invocation.getThis()).andReturn(new Object()); ctx.publishEvent(isA(MyEvent.class)); replay(invocation, ctx); interceptor.invoke(invocation); verify(invocation, ctx); } @Test public void listenersInApplicationContext() { StaticApplicationContext context = new StaticApplicationContext(); context.registerBeanDefinition("listener1", new RootBeanDefinition(MyOrderedListener1.class)); RootBeanDefinition listener2 = new RootBeanDefinition(MyOrderedListener2.class); listener2.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("listener1")); context.registerBeanDefinition("listener2", listener2); context.refresh(); MyOrderedListener1 listener1 = context.getBean("listener1", MyOrderedListener1.class); MyEvent event1 = new MyEvent(context); context.publishEvent(event1); MyOtherEvent event2 = new MyOtherEvent(context); context.publishEvent(event2); MyEvent event3 = new MyEvent(context); context.publishEvent(event3); MyOtherEvent event4 = new MyOtherEvent(context); context.publishEvent(event4); assertTrue(listener1.seenEvents.contains(event1)); assertTrue(listener1.seenEvents.contains(event2)); assertTrue(listener1.seenEvents.contains(event3)); assertTrue(listener1.seenEvents.contains(event4)); listener1.seenEvents.clear(); context.publishEvent(event1); context.publishEvent(event2); context.publishEvent(event3); context.publishEvent(event4); assertTrue(listener1.seenEvents.contains(event1)); assertTrue(listener1.seenEvents.contains(event2)); assertTrue(listener1.seenEvents.contains(event3)); assertTrue(listener1.seenEvents.contains(event4)); } @Test public void nonSingletonListenerInApplicationContext() { StaticApplicationContext context = new StaticApplicationContext(); RootBeanDefinition listener = new RootBeanDefinition(MyNonSingletonListener.class); listener.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); context.registerBeanDefinition("listener", listener); context.refresh(); MyEvent event1 = new MyEvent(context); context.publishEvent(event1); MyOtherEvent event2 = new MyOtherEvent(context); context.publishEvent(event2); MyEvent event3 = new MyEvent(context); context.publishEvent(event3); MyOtherEvent event4 = new MyOtherEvent(context); context.publishEvent(event4); assertTrue(MyNonSingletonListener.seenEvents.contains(event1)); assertTrue(MyNonSingletonListener.seenEvents.contains(event2)); assertTrue(MyNonSingletonListener.seenEvents.contains(event3)); assertTrue(MyNonSingletonListener.seenEvents.contains(event4)); MyNonSingletonListener.seenEvents.clear(); } @Test public void listenerAndBroadcasterWithCircularReference() { StaticApplicationContext context = new StaticApplicationContext(); context.registerBeanDefinition("broadcaster", new RootBeanDefinition(BeanThatBroadcasts.class)); RootBeanDefinition listenerDef = new RootBeanDefinition(BeanThatListens.class); listenerDef.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("broadcaster")); context.registerBeanDefinition("listener", listenerDef); context.refresh(); BeanThatBroadcasts broadcaster = context.getBean("broadcaster", BeanThatBroadcasts.class); context.publishEvent(new MyEvent(context)); assertEquals("The event was not received by the listener", 2, broadcaster.receivedCount); } @Test public void innerBeanAsListener() { StaticApplicationContext context = new StaticApplicationContext(); RootBeanDefinition listenerDef = new RootBeanDefinition(TestBean.class); listenerDef.getPropertyValues().add("friends", new RootBeanDefinition(BeanThatListens.class)); context.registerBeanDefinition("listener", listenerDef); context.refresh(); context.publishEvent(new MyEvent(this)); context.publishEvent(new MyEvent(this)); TestBean listener = context.getBean(TestBean.class); assertEquals(3, ((BeanThatListens) listener.getFriends().iterator().next()).getEventCount()); } public static class MyEvent extends ApplicationEvent { public MyEvent(Object source) { super(source); } } public static class MyOtherEvent extends ApplicationEvent { public MyOtherEvent(Object source) { super(source); } } public static class MyOrderedListener1 implements ApplicationListener, Ordered { public final Set<ApplicationEvent> seenEvents = new HashSet<ApplicationEvent>(); public void onApplicationEvent(ApplicationEvent event) { this.seenEvents.add(event); } public int getOrder() { return 0; } } public interface MyOrderedListenerIfc<E extends ApplicationEvent> extends ApplicationListener<E>, Ordered { } public static abstract class MyOrderedListenerBase implements MyOrderedListenerIfc<MyEvent> { public int getOrder() { return 1; } } public static class MyOrderedListener2 extends MyOrderedListenerBase { private final MyOrderedListener1 otherListener; public MyOrderedListener2(MyOrderedListener1 otherListener) { this.otherListener = otherListener; } public void onApplicationEvent(MyEvent event) { assertTrue(otherListener.seenEvents.contains(event)); } } public static class MyNonSingletonListener implements ApplicationListener { public static final Set<ApplicationEvent> seenEvents = new HashSet<ApplicationEvent>(); public void onApplicationEvent(ApplicationEvent event) { seenEvents.add(event); } } }