From 1284086ffad7eccc43b883c865d72e58de83c905 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Mon, 11 Jan 2010 18:36:48 +0000 Subject: [PATCH] SPR-6669 @Scheduled may now be used as a meta-annotation --- .../scheduling/annotation/Scheduled.java | 4 +- ...duledAnnotationBeanPostProcessorTests.java | 86 ++++++++++++++++++- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index edb74e204ba..b1832076183 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * 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. @@ -35,7 +35,7 @@ import java.lang.annotation.Target; * @since 3.0 * @see ScheduledAnnotationBeanPostProcessor */ -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Scheduled { diff --git a/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java b/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java index 40aa8fed043..bf8aec23fa4 100644 --- a/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java +++ b/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * 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. @@ -18,6 +18,10 @@ package org.springframework.scheduling.annotation; import static org.junit.Assert.assertEquals; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.Map; import org.junit.Test; @@ -33,7 +37,7 @@ import org.springframework.scheduling.support.MethodInvokingRunnable; /** * @author Mark Fisher */ -@SuppressWarnings("unchecked") +@SuppressWarnings({"unchecked", "unused"}) public class ScheduledAnnotationBeanPostProcessorTests { @Test @@ -97,7 +101,7 @@ public class ScheduledAnnotationBeanPostProcessorTests { Object target = context.getBean("target"); ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); - Map cronTasks = (Map) + Map cronTasks = (Map) new DirectFieldAccessor(registrar).getPropertyValue("cronTasks"); assertEquals(1, cronTasks.size()); MethodInvokingRunnable runnable = (MethodInvokingRunnable) cronTasks.keySet().iterator().next(); @@ -108,6 +112,54 @@ public class ScheduledAnnotationBeanPostProcessorTests { assertEquals("*/7 * * * * ?", cronTasks.values().iterator().next()); } + @Test + public void metaAnnotationWithFixedRate() { + StaticApplicationContext context = new StaticApplicationContext(); + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition( + ScheduledAnnotationBeanPostProcessorTests.MetaAnnotationFixedRateTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + Object postProcessor = context.getBean("postProcessor"); + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + Map fixedRateTasks = (Map) + new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks"); + assertEquals(1, fixedRateTasks.size()); + MethodInvokingRunnable runnable = (MethodInvokingRunnable) fixedRateTasks.keySet().iterator().next(); + Object targetObject = runnable.getTargetObject(); + String targetMethod = runnable.getTargetMethod(); + assertEquals(target, targetObject); + assertEquals("checkForUpdates", targetMethod); + assertEquals(new Long(5000), fixedRateTasks.values().iterator().next()); + } + + @Test + public void metaAnnotationWithCronExpression() { + StaticApplicationContext context = new StaticApplicationContext(); + BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class); + BeanDefinition targetDefinition = new RootBeanDefinition( + ScheduledAnnotationBeanPostProcessorTests.MetaAnnotationCronTestBean.class); + context.registerBeanDefinition("postProcessor", processorDefinition); + context.registerBeanDefinition("target", targetDefinition); + context.refresh(); + Object postProcessor = context.getBean("postProcessor"); + Object target = context.getBean("target"); + ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar) + new DirectFieldAccessor(postProcessor).getPropertyValue("registrar"); + Map cronTasks = (Map) + new DirectFieldAccessor(registrar).getPropertyValue("cronTasks"); + assertEquals(1, cronTasks.size()); + MethodInvokingRunnable runnable = (MethodInvokingRunnable) cronTasks.keySet().iterator().next(); + Object targetObject = runnable.getTargetObject(); + String targetMethod = runnable.getTargetMethod(); + assertEquals(target, targetObject); + assertEquals("generateReport", targetMethod); + assertEquals("0 0 * * * ?", cronTasks.values().iterator().next()); + } + @Test(expected = BeanCreationException.class) public void emptyAnnotation() { StaticApplicationContext context = new StaticApplicationContext(); @@ -216,4 +268,32 @@ public class ScheduledAnnotationBeanPostProcessorTests { } + + @Scheduled(fixedRate = 5000) + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + private static @interface EveryFiveSeconds {} + + + @Scheduled(cron = "0 0 * * * ?") + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + private static @interface Hourly {} + + + private static class MetaAnnotationFixedRateTestBean { + + @EveryFiveSeconds + public void checkForUpdates() { + } + } + + + private static class MetaAnnotationCronTestBean { + + @Hourly + public void generateReport() { + } + } + }