Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
2c746326
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2c746326
编写于
6月 06, 2009
作者:
M
Mark Fisher
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Initial commit of @Scheduled annotation and ScheduledAnnotationBeanPostProcessor.
上级
6dd2ce94
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
414 addition
and
0 deletion
+414
-0
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java
.../org/springframework/scheduling/annotation/Scheduled.java
+48
-0
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
...ling/annotation/ScheduledAnnotationBeanPostProcessor.java
+147
-0
org.springframework.context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java
...annotation/ScheduledAnnotationBeanPostProcessorTests.java
+219
-0
未找到文件。
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java
0 → 100644
浏览文件 @
2c746326
/*
* 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.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Annotation that marks a method to be scheduled. Exactly one of the
* <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code>
* attributes must be provided.
*
* <p>The annotated method must expect no arguments and have a
* <code>void</code> return type.
*
* @author Mark Fisher
* @since 3.0
* @see ScheduledAnnotationBeanPostProcessor
*/
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
Scheduled
{
String
cron
()
default
""
;
long
fixedDelay
()
default
-
1
;
long
fixedRate
()
default
-
1
;
}
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
0 → 100644
浏览文件 @
2c746326
/*
* 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.lang.reflect.Method
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.springframework.aop.support.AopUtils
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.DisposableBean
;
import
org.springframework.beans.factory.config.BeanPostProcessor
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.context.event.ContextRefreshedEvent
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.scheduling.config.ScheduledTaskRegistrar
;
import
org.springframework.scheduling.support.MethodInvokingRunnable
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.util.ReflectionUtils.MethodCallback
;
/**
* Bean post-processor that registers methods annotated with
* {@link Scheduled @Scheduled} to be invoked by a TaskScheduler according
* to the fixedRate, fixedDelay, or cron expression provided via the annotation.
*
* @author Mark Fisher
* @since 3.0
* @see Scheduled
*/
public
class
ScheduledAnnotationBeanPostProcessor
implements
BeanPostProcessor
,
Ordered
,
ApplicationListener
<
ContextRefreshedEvent
>,
DisposableBean
{
private
Object
scheduler
;
private
final
ScheduledTaskRegistrar
registrar
=
new
ScheduledTaskRegistrar
();
private
final
Map
<
Runnable
,
String
>
cronTasks
=
new
HashMap
<
Runnable
,
String
>();
private
final
Map
<
Runnable
,
Long
>
fixedDelayTasks
=
new
HashMap
<
Runnable
,
Long
>();
private
final
Map
<
Runnable
,
Long
>
fixedRateTasks
=
new
HashMap
<
Runnable
,
Long
>();
/**
* Set the {@link org.springframework.scheduling.TaskScheduler} that will
* invoke the scheduled methods or a
* {@link java.util.concurrent.ScheduledExecutorService} to be wrapped
* within an instance of
* {@link org.springframework.scheduling.concurrent.ConcurrentTaskScheduler}.
*/
public
void
setScheduler
(
Object
scheduler
)
{
this
.
scheduler
=
scheduler
;
}
public
int
getOrder
()
{
return
LOWEST_PRECEDENCE
;
}
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
bean
;
}
public
Object
postProcessAfterInitialization
(
final
Object
bean
,
String
beanName
)
throws
BeansException
{
Class
<?>
targetClass
=
AopUtils
.
getTargetClass
(
bean
);
if
(
targetClass
==
null
)
{
return
bean
;
}
ReflectionUtils
.
doWithMethods
(
targetClass
,
new
MethodCallback
()
{
@Override
public
void
doWith
(
Method
method
)
throws
IllegalArgumentException
,
IllegalAccessException
{
Scheduled
annotation
=
AnnotationUtils
.
getAnnotation
(
method
,
Scheduled
.
class
);
if
(
annotation
!=
null
)
{
Assert
.
isTrue
(
void
.
class
.
equals
(
method
.
getReturnType
()),
"Only void-returning methods may be annotated with @Scheduled."
);
Assert
.
isTrue
(
method
.
getParameterTypes
().
length
==
0
,
"Only no-arg methods may be annotated with @Scheduled."
);
MethodInvokingRunnable
runnable
=
new
MethodInvokingRunnable
();
runnable
.
setTargetObject
(
bean
);
runnable
.
setTargetMethod
(
method
.
getName
());
runnable
.
setArguments
(
new
Object
[
0
]);
try
{
runnable
.
prepare
();
}
catch
(
Exception
e
)
{
throw
new
IllegalStateException
(
"failed to prepare task"
,
e
);
}
boolean
processedSchedule
=
false
;
String
errorMessage
=
"Exactly one of 'cron', 'fixedDelay', or 'fixedRate' is required."
;
String
cron
=
annotation
.
cron
();
if
(!
""
.
equals
(
cron
))
{
processedSchedule
=
true
;
cronTasks
.
put
(
runnable
,
cron
);
}
long
fixedDelay
=
annotation
.
fixedDelay
();
if
(
fixedDelay
>=
0
)
{
Assert
.
isTrue
(!
processedSchedule
,
errorMessage
);
processedSchedule
=
true
;
fixedDelayTasks
.
put
(
runnable
,
new
Long
(
fixedDelay
));
}
long
fixedRate
=
annotation
.
fixedRate
();
if
(
fixedRate
>=
0
)
{
Assert
.
isTrue
(!
processedSchedule
,
errorMessage
);
processedSchedule
=
true
;
fixedRateTasks
.
put
(
runnable
,
new
Long
(
fixedRate
));
}
Assert
.
isTrue
(
processedSchedule
,
errorMessage
);
}
}
});
return
bean
;
}
@Override
public
void
onApplicationEvent
(
ContextRefreshedEvent
event
)
{
if
(
scheduler
!=
null
)
{
this
.
registrar
.
setScheduler
(
scheduler
);
}
this
.
registrar
.
setCronTasks
(
this
.
cronTasks
);
this
.
registrar
.
setFixedDelayTasks
(
this
.
fixedDelayTasks
);
this
.
registrar
.
setFixedRateTasks
(
this
.
fixedRateTasks
);
this
.
registrar
.
afterPropertiesSet
();
}
@Override
public
void
destroy
()
throws
Exception
{
if
(
this
.
registrar
!=
null
)
{
this
.
registrar
.
destroy
();
}
}
}
org.springframework.context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java
0 → 100644
浏览文件 @
2c746326
/*
* 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
static
org
.
junit
.
Assert
.
assertEquals
;
import
java.util.Map
;
import
org.junit.Test
;
import
org.springframework.beans.DirectFieldAccessor
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.context.support.StaticApplicationContext
;
import
org.springframework.scheduling.config.ScheduledTaskRegistrar
;
import
org.springframework.scheduling.support.MethodInvokingRunnable
;
/**
* @author Mark Fisher
*/
@SuppressWarnings
(
"unchecked"
)
public
class
ScheduledAnnotationBeanPostProcessorTests
{
@Test
public
void
fixedDelayTask
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
FixedDelayTestBean
.
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
<
Runnable
,
Long
>
fixedDelayTasks
=
(
Map
<
Runnable
,
Long
>)
new
DirectFieldAccessor
(
registrar
).
getPropertyValue
(
"fixedDelayTasks"
);
assertEquals
(
1
,
fixedDelayTasks
.
size
());
MethodInvokingRunnable
runnable
=
(
MethodInvokingRunnable
)
fixedDelayTasks
.
keySet
().
iterator
().
next
();
Object
targetObject
=
runnable
.
getTargetObject
();
String
targetMethod
=
runnable
.
getTargetMethod
();
assertEquals
(
target
,
targetObject
);
assertEquals
(
"fixedDelay"
,
targetMethod
);
assertEquals
(
new
Long
(
5000
),
fixedDelayTasks
.
values
().
iterator
().
next
());
}
@Test
public
void
fixedRateTask
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
FixedRateTestBean
.
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
<
Runnable
,
Long
>
fixedRateTasks
=
(
Map
<
Runnable
,
Long
>)
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
(
"fixedRate"
,
targetMethod
);
assertEquals
(
new
Long
(
3000
),
fixedRateTasks
.
values
().
iterator
().
next
());
}
@Test
public
void
cronTask
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
CronTestBean
.
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
<
Runnable
,
Long
>
cronTasks
=
(
Map
<
Runnable
,
Long
>)
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
(
"cron"
,
targetMethod
);
assertEquals
(
"*/7 * * * * ?"
,
cronTasks
.
values
().
iterator
().
next
());
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
emptyAnnotation
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
EmptyAnnotationTestBean
.
class
);
context
.
registerBeanDefinition
(
"postProcessor"
,
processorDefinition
);
context
.
registerBeanDefinition
(
"target"
,
targetDefinition
);
context
.
refresh
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
invalidCron
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
InvalidCronTestBean
.
class
);
context
.
registerBeanDefinition
(
"postProcessor"
,
processorDefinition
);
context
.
registerBeanDefinition
(
"target"
,
targetDefinition
);
context
.
refresh
();
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
nonVoidReturnType
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
NonVoidReturnTypeTestBean
.
class
);
context
.
registerBeanDefinition
(
"postProcessor"
,
processorDefinition
);
context
.
registerBeanDefinition
(
"target"
,
targetDefinition
);
context
.
refresh
();
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
nonEmptyParamList
()
{
StaticApplicationContext
context
=
new
StaticApplicationContext
();
BeanDefinition
processorDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessor
.
class
);
BeanDefinition
targetDefinition
=
new
RootBeanDefinition
(
ScheduledAnnotationBeanPostProcessorTests
.
NonEmptyParamListTestBean
.
class
);
context
.
registerBeanDefinition
(
"postProcessor"
,
processorDefinition
);
context
.
registerBeanDefinition
(
"target"
,
targetDefinition
);
context
.
refresh
();
}
private
static
class
FixedDelayTestBean
{
@Scheduled
(
fixedDelay
=
5000
)
public
void
fixedDelay
()
{
}
}
private
static
class
FixedRateTestBean
{
@Scheduled
(
fixedRate
=
3000
)
public
void
fixedRate
()
{
}
}
private
static
class
CronTestBean
{
@Scheduled
(
cron
=
"*/7 * * * * ?"
)
public
void
cron
()
{
}
}
private
static
class
EmptyAnnotationTestBean
{
@Scheduled
public
void
invalid
()
{
}
}
private
static
class
InvalidCronTestBean
{
@Scheduled
(
cron
=
"abc"
)
public
void
invalid
()
{
}
}
private
static
class
NonVoidReturnTypeTestBean
{
@Scheduled
(
fixedRate
=
3000
)
public
String
invalid
()
{
return
"oops"
;
}
}
private
static
class
NonEmptyParamListTestBean
{
@Scheduled
(
fixedRate
=
3000
)
public
void
invalid
(
String
oops
)
{
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录