/* * Copyright 2002-2008 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.annotation; import javax.annotation.Resource; import junit.framework.TestCase; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.ITestBean; import org.springframework.beans.TestBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.support.GenericApplicationContext; import org.springframework.util.StopWatch; /** * @author Juergen Hoeller * @since 2.5 */ public class AnnotationProcessorPerformanceTests extends TestCase { private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class); public void testPrototypeCreationWithResourcePropertiesIsFastEnough() { if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { // Skip this test: Trace logging blows the time limit. return; } GenericApplicationContext ctx = new GenericApplicationContext(); AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx); ctx.refresh(); RootBeanDefinition rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class); rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); ctx.registerBeanDefinition("test", rbd); ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class)); TestBean spouse = (TestBean) ctx.getBean("spouse"); StopWatch sw = new StopWatch(); sw.start("prototype"); for (int i = 0; i < 100000; i++) { TestBean tb = (TestBean) ctx.getBean("test"); assertSame(spouse, tb.getSpouse()); } sw.stop(); //System.out.println(sw.getTotalTimeMillis()); assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000); } public void testPrototypeCreationWithOverriddenResourcePropertiesIsFastEnough() { if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { // Skip this test: Trace logging blows the time limit. return; } GenericApplicationContext ctx = new GenericApplicationContext(); AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx); ctx.refresh(); RootBeanDefinition rbd = new RootBeanDefinition(ResourceAnnotatedTestBean.class); rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); rbd.getPropertyValues().addPropertyValue("spouse", new RuntimeBeanReference("spouse")); ctx.registerBeanDefinition("test", rbd); ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class)); TestBean spouse = (TestBean) ctx.getBean("spouse"); StopWatch sw = new StopWatch(); sw.start("prototype"); for (int i = 0; i < 100000; i++) { TestBean tb = (TestBean) ctx.getBean("test"); assertSame(spouse, tb.getSpouse()); } sw.stop(); //System.out.println(sw.getTotalTimeMillis()); assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000); } public void testPrototypeCreationWithAutowiredPropertiesIsFastEnough() { if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { // Skip this test: Trace logging blows the time limit. return; } GenericApplicationContext ctx = new GenericApplicationContext(); AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx); ctx.refresh(); RootBeanDefinition rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class); rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); ctx.registerBeanDefinition("test", rbd); ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class)); TestBean spouse = (TestBean) ctx.getBean("spouse"); StopWatch sw = new StopWatch(); sw.start("prototype"); for (int i = 0; i < 100000; i++) { TestBean tb = (TestBean) ctx.getBean("test"); assertSame(spouse, tb.getSpouse()); } sw.stop(); //System.out.println(sw.getTotalTimeMillis()); assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000); } public void testPrototypeCreationWithOverriddenAutowiredPropertiesIsFastEnough() { if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { // Skip this test: Trace logging blows the time limit. return; } GenericApplicationContext ctx = new GenericApplicationContext(); AnnotationConfigUtils.registerAnnotationConfigProcessors(ctx); ctx.refresh(); RootBeanDefinition rbd = new RootBeanDefinition(AutowiredAnnotatedTestBean.class); rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); rbd.getPropertyValues().addPropertyValue("spouse", new RuntimeBeanReference("spouse")); ctx.registerBeanDefinition("test", rbd); ctx.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class)); TestBean spouse = (TestBean) ctx.getBean("spouse"); StopWatch sw = new StopWatch(); sw.start("prototype"); for (int i = 0; i < 100000; i++) { TestBean tb = (TestBean) ctx.getBean("test"); assertSame(spouse, tb.getSpouse()); } sw.stop(); //System.out.println(sw.getTotalTimeMillis()); assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000); } private static class ResourceAnnotatedTestBean extends TestBean { @Resource @Required public void setSpouse(ITestBean spouse) { super.setSpouse(spouse); } } private static class AutowiredAnnotatedTestBean extends TestBean { @Autowired @Required public void setSpouse(ITestBean spouse) { super.setSpouse(spouse); } } }