/* * Copyright 2002-2009 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.scheduling.annotation; import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.support.GenericApplicationContext; import org.springframework.scheduling.annotation.AsyncResult; /** * @author Juergen Hoeller */ public class AsyncExecutionTests { private static String originalThreadName; private static int listenerCalled = 0; private static int listenerConstructed = 0; @Test public void asyncMethods() throws Exception { originalThreadName = Thread.currentThread().getName(); GenericApplicationContext context = new GenericApplicationContext(); context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodBean.class)); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); AsyncMethodBean asyncTest = context.getBean("asyncTest", AsyncMethodBean.class); asyncTest.doNothing(5); asyncTest.doSomething(10); Future<String> future = asyncTest.returnSomething(20); assertEquals("20", future.get()); } @Test public void asyncClass() throws Exception { originalThreadName = Thread.currentThread().getName(); GenericApplicationContext context = new GenericApplicationContext(); context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncClassBean.class)); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); AsyncClassBean asyncTest = context.getBean("asyncTest", AsyncClassBean.class); asyncTest.doSomething(10); Future<String> future = asyncTest.returnSomething(20); assertEquals("20", future.get()); } @Test public void asyncInterface() throws Exception { originalThreadName = Thread.currentThread().getName(); GenericApplicationContext context = new GenericApplicationContext(); context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncInterfaceBean.class)); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); AsyncInterface asyncTest = context.getBean("asyncTest", AsyncInterface.class); asyncTest.doSomething(10); Future<String> future = asyncTest.returnSomething(20); assertEquals("20", future.get()); } @Test public void asyncMethodsInInterface() throws Exception { originalThreadName = Thread.currentThread().getName(); GenericApplicationContext context = new GenericApplicationContext(); context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodsInterfaceBean.class)); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); AsyncMethodsInterface asyncTest = context.getBean("asyncTest", AsyncMethodsInterface.class); asyncTest.doNothing(5); asyncTest.doSomething(10); Future<String> future = asyncTest.returnSomething(20); assertEquals("20", future.get()); } @Test public void asyncMethodListener() throws Exception { originalThreadName = Thread.currentThread().getName(); listenerCalled = 0; GenericApplicationContext context = new GenericApplicationContext(); context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodListener.class)); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); Thread.sleep(1000); assertEquals(1, listenerCalled); } @Test public void asyncClassListener() throws Exception { originalThreadName = Thread.currentThread().getName(); listenerCalled = 0; listenerConstructed = 0; GenericApplicationContext context = new GenericApplicationContext(); context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncClassListener.class)); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); context.close(); Thread.sleep(1000); assertEquals(2, listenerCalled); assertEquals(1, listenerConstructed); } @Test public void asyncPrototypeClassListener() throws Exception { originalThreadName = Thread.currentThread().getName(); listenerCalled = 0; listenerConstructed = 0; GenericApplicationContext context = new GenericApplicationContext(); RootBeanDefinition listenerDef = new RootBeanDefinition(AsyncClassListener.class); listenerDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); context.registerBeanDefinition("asyncTest", listenerDef); context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); context.refresh(); context.close(); Thread.sleep(1000); assertEquals(2, listenerCalled); assertEquals(2, listenerConstructed); } public static class AsyncMethodBean { public void doNothing(int i) { assertTrue(Thread.currentThread().getName().equals(originalThreadName)); } @Async public void doSomething(int i) { System.out.println(Thread.currentThread().getName() + ": " + i); assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); } @Async public Future<String> returnSomething(int i) { assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); return new AsyncResult<String>(Integer.toString(i)); } } @Async public static class AsyncClassBean { public void doSomething(int i) { System.out.println(Thread.currentThread().getName() + ": " + i); assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); } public Future<String> returnSomething(int i) { assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); return new AsyncResult<String>(Integer.toString(i)); } } @Async public interface AsyncInterface { void doSomething(int i); Future<String> returnSomething(int i); } public static class AsyncInterfaceBean implements AsyncInterface { public void doSomething(int i) { System.out.println(Thread.currentThread().getName() + ": " + i); assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); } public Future<String> returnSomething(int i) { assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); return new AsyncResult<String>(Integer.toString(i)); } } public interface AsyncMethodsInterface { void doNothing(int i); @Async void doSomething(int i); @Async Future<String> returnSomething(int i); } public static class AsyncMethodsInterfaceBean implements AsyncMethodsInterface { public void doNothing(int i) { assertTrue(Thread.currentThread().getName().equals(originalThreadName)); } public void doSomething(int i) { System.out.println(Thread.currentThread().getName() + ": " + i); assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); } public Future<String> returnSomething(int i) { assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); return new AsyncResult<String>(Integer.toString(i)); } } public static class AsyncMethodListener implements ApplicationListener { @Async public void onApplicationEvent(ApplicationEvent event) { listenerCalled++; assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); } } @Async public static class AsyncClassListener implements ApplicationListener { public AsyncClassListener() { listenerConstructed++; } public void onApplicationEvent(ApplicationEvent event) { listenerCalled++; assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); } } }