From df6ba69bc5661b79a0b438e339ae72f9251c86d9 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Sat, 6 Jun 2009 02:11:39 +0000 Subject: [PATCH] The element now registers the post-processor for @Scheduled in addition to the already existing @Async support. Both "scheduler" and "executor" attributes are available. --- .../AnnotationDrivenBeanDefinitionParser.java | 32 +++++++-- .../scheduling/config/spring-task-3.0.xsd | 10 +++ ...tationDrivenBeanDefinitionParserTests.java | 69 +++++++++++++++++++ .../config/annotationDrivenContext.xml | 16 +++++ 4 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 org.springframework.context/src/test/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParserTests.java create mode 100644 org.springframework.context/src/test/resources/org/springframework/scheduling/config/annotationDrivenContext.xml diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParser.java index 928c77629ca..6480c5c0d7a 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParser.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParser.java @@ -42,6 +42,12 @@ public class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParse public static final String ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME = "org.springframework.scheduling.annotation.internalAsyncAnnotationProcessor"; + /** + * The bean name of the internally managed scheduled annotation processor. + */ + public static final String SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME = + "org.springframework.scheduling.annotation.internalScheduledAnnotationProcessor"; + public BeanDefinition parse(Element element, ParserContext parserContext) { Object source = parserContext.extractSource(element); @@ -64,8 +70,21 @@ public class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParse if (StringUtils.hasText(executor)) { builder.addPropertyReference("executor", executor); } - BeanDefinitionHolder holder = registerPostProcessor(registry, builder, ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME); - parserContext.registerComponent(new BeanComponentDefinition(holder)); + registerPostProcessor(parserContext, builder, ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME); + } + if (registry.containsBeanDefinition(SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)) { + parserContext.getReaderContext().error( + "Only one ScheduledAnnotationBeanPostProcessor may exist within the context.", source); + } + else { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( + "org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor"); + builder.getRawBeanDefinition().setSource(source); + String scheduler = element.getAttribute("scheduler"); + if (StringUtils.hasText(scheduler)) { + builder.addPropertyReference("scheduler", scheduler); + } + registerPostProcessor(parserContext, builder, SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME); } // Finally register the composite component. @@ -74,12 +93,13 @@ public class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParse return null; } - private static BeanDefinitionHolder registerPostProcessor( - BeanDefinitionRegistry registry, BeanDefinitionBuilder builder, String beanName) { + private static void registerPostProcessor( + ParserContext parserContext, BeanDefinitionBuilder builder, String beanName) { builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - registry.registerBeanDefinition(beanName, builder.getBeanDefinition()); - return new BeanDefinitionHolder(builder.getBeanDefinition(), beanName); + parserContext.getRegistry().registerBeanDefinition(beanName, builder.getBeanDefinition()); + BeanDefinitionHolder holder = new BeanDefinitionHolder(builder.getBeanDefinition(), beanName); + parserContext.registerComponent(new BeanComponentDefinition(holder)); } } diff --git a/org.springframework.context/src/main/resources/org/springframework/scheduling/config/spring-task-3.0.xsd b/org.springframework.context/src/main/resources/org/springframework/scheduling/config/spring-task-3.0.xsd index 65263d08b68..a8d7b4e00cc 100644 --- a/org.springframework.context/src/main/resources/org/springframework/scheduling/config/spring-task-3.0.xsd +++ b/org.springframework.context/src/main/resources/org/springframework/scheduling/config/spring-task-3.0.xsd @@ -34,6 +34,16 @@ ]]> + + + + + diff --git a/org.springframework.context/src/test/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParserTests.java b/org.springframework.context/src/test/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParserTests.java new file mode 100644 index 00000000000..6ac37bda032 --- /dev/null +++ b/org.springframework.context/src/test/java/org/springframework/scheduling/config/AnnotationDrivenBeanDefinitionParserTests.java @@ -0,0 +1,69 @@ +/* + * 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.config; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +import org.springframework.beans.DirectFieldAccessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * @author Mark Fisher + */ +public class AnnotationDrivenBeanDefinitionParserTests { + + private ApplicationContext context; + + + @Before + public void setup() { + this.context = new ClassPathXmlApplicationContext( + "annotationDrivenContext.xml", AnnotationDrivenBeanDefinitionParserTests.class); + } + + @Test + public void asyncPostProcessorRegistered() { + assertTrue(context.containsBean( + AnnotationDrivenBeanDefinitionParser.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)); + } + + @Test + public void scheduledPostProcessorRegistered() { + assertTrue(context.containsBean( + AnnotationDrivenBeanDefinitionParser.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)); + } + + @Test + public void asyncPostProcessorExecutorReference() { + Object executor = context.getBean("testExecutor"); + Object postProcessor = context.getBean(AnnotationDrivenBeanDefinitionParser.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME); + assertSame(executor, new DirectFieldAccessor(postProcessor).getPropertyValue("executor")); + } + + @Test + public void scheduledPostProcessorSchedulerReference() { + Object scheduler = context.getBean("testScheduler"); + Object postProcessor = context.getBean(AnnotationDrivenBeanDefinitionParser.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME); + assertSame(scheduler, new DirectFieldAccessor(postProcessor).getPropertyValue("scheduler")); + } + +} diff --git a/org.springframework.context/src/test/resources/org/springframework/scheduling/config/annotationDrivenContext.xml b/org.springframework.context/src/test/resources/org/springframework/scheduling/config/annotationDrivenContext.xml new file mode 100644 index 00000000000..72ca66bf391 --- /dev/null +++ b/org.springframework.context/src/test/resources/org/springframework/scheduling/config/annotationDrivenContext.xml @@ -0,0 +1,16 @@ + + + + + + + + + +