Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
777a104d
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,体验更适合开发者的 AI 搜索 >>
提交
777a104d
编写于
2月 10, 2009
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
added @Async annotation, AsyncExecutionInterceptor, AsyncAnnotationAdvisor
上级
21a442b2
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
752 addition
and
48 deletion
+752
-48
build-spring-framework/resources/changelog.txt
build-spring-framework/resources/changelog.txt
+26
-4
org.springframework.aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java
...gframework/aop/interceptor/AsyncExecutionInterceptor.java
+103
-0
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Async.java
...java/org/springframework/scheduling/annotation/Async.java
+49
-0
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java
...amework/scheduling/annotation/AsyncAnnotationAdvisor.java
+149
-0
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java
...rg/springframework/scheduling/annotation/AsyncResult.java
+63
-0
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/package.html
...va/org/springframework/scheduling/annotation/package.html
+7
-0
org.springframework.context/src/test/java/example/scannable/AutowiredQualifierFooService.java
.../java/example/scannable/AutowiredQualifierFooService.java
+8
-1
org.springframework.context/src/test/java/example/scannable/FooService.java
...k.context/src/test/java/example/scannable/FooService.java
+9
-2
org.springframework.context/src/test/java/example/scannable/FooServiceImpl.java
...ntext/src/test/java/example/scannable/FooServiceImpl.java
+10
-2
org.springframework.context/src/test/java/example/scannable/ScopedProxyTestBean.java
.../src/test/java/example/scannable/ScopedProxyTestBean.java
+8
-1
org.springframework.context/src/test/java/example/scannable/ServiceInvocationCounter.java
...test/java/example/scannable/ServiceInvocationCounter.java
+9
-0
org.springframework.context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java
...ntext/annotation/ClassPathBeanDefinitionScannerTests.java
+18
-20
org.springframework.context/src/test/java/org/springframework/context/annotation/SimpleConfigTests.java
...springframework/context/annotation/SimpleConfigTests.java
+19
-13
org.springframework.context/src/test/java/org/springframework/context/annotation/simpleConfigTests.xml
.../springframework/context/annotation/simpleConfigTests.xml
+13
-5
org.springframework.context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java
...gframework/scheduling/annotation/AsyncExecutionTests.java
+261
-0
未找到文件。
build-spring-framework/resources/changelog.txt
浏览文件 @
777a104d
...
...
@@ -3,15 +3,36 @@ SPRING FRAMEWORK CHANGELOG
http://www.springsource.org
Changes in version 3.0.0.M2 (2009-0
1-23
)
Changes in version 3.0.0.M2 (2009-0
2-11
)
----------------------------------------
* "systemProperties" bean is not considered a default match for type Properties anymore
* registered plain singletons will be fully matched according to their qualifiers
* all "taskExecutor" bean properties now accept any "java.util.concurrent.Executor"
* added "Future submit(Runnable)" and "Future submit(Callable)" to AsyncTaskExecutor
* SimpleAsyncTaskExecutor supports a custom "java.util.concurrent.ThreadFactory"
* SchedulingTaskExecutor interface extends AsyncTaskExecutor now
* added ThreadPoolExecutorFactoryBean (exposing the native ExecutorService interface)
* added ExecutorServiceAdapter class as a standard wrapper for a Spring TaskExecutor
* reduced backport-concurrent support to TaskExecutor adapters
* added @Async annotation and AsyncAnnotationAdvisor (namespace support coming in M3)
* EJB 3.1's @Asynchronous annotation gets detected and supported by default as well
* ApplicationListener beans get obtained on demand, supporting non-singletons as well
* ApplicationListeners will be called in the order according to the Ordered contract
* generified ApplicationListener interface, narrowing the event type to be received
* generified Hibernate/Jdo/JpaCallback with generic "doInXxx" return type
* HibernateOperations uses generic parameter/return types where possible
* JdoOperations uses generic parameter/return types where possible (following JDO 2.1)
* removed "flush" operation from JdoDialect (fully relying on JDO 2.0+ compliance now)
* added JDO 2.1 compliant StandardPersistenceManagerProxy/SpringPersistenceManagerProxy
* Spring-created EntityManagers support JPA 2.0 draft API ("unwrap", "getQueryBuilder")
* Spring initiates JPA 2.0 query timeout with remaining Spring transaction timeout
* added support for WebSphere's ResourceAdapter-managed messaging transactions
* introduced OXM support package (originating from Spring Web Services)
* introduced OXM-based MarshallingMessageConverter for JMS
* introduced OXM-based MarshallingView for Spring MVC
* refined @PathVariable handling
* updated Spring Portlet mocks for Portlet API 2.0
* updated Spring Portlet MVC infrastructure for Portlet API 2.0
* refined @PathVariable handling in MVC handler methods
* updated Spring Portlet MVC infrastructure and mocks for Portlet API 2.0
* added resource and event methods to Portlet HandlerAdapter/HandlerInterceptor
* added resolveException method for resource requests to HandlerExceptionResolver
* introduced Resource/EventAwareController subinterfaces of Portlet Controller
...
...
@@ -34,6 +55,7 @@ Changes in version 3.0.0.M1 (2008-12-05)
* removed ContextLoaderServlet and Log4jConfigServlet
* deprecated form controller hierarchy in favor of @MVC form object handling
* deprecated JUnit 3.8 test class hierarchy in favor of test context framework
* revised TaskExecutor interface to extend "java.util.concurrent.Executor" now
* introduced Spring EL parser in org.springframework.expression package
* introduced #{...} expression support in bean definitions
* introduced @Value annotation for embedded expression support
...
...
org.springframework.aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java
0 → 100644
浏览文件 @
777a104d
/*
* 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.aop.interceptor
;
import
java.util.concurrent.Callable
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.Future
;
import
org.aopalliance.intercept.MethodInterceptor
;
import
org.aopalliance.intercept.MethodInvocation
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.task.AsyncTaskExecutor
;
import
org.springframework.core.task.support.TaskExecutorAdapter
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ReflectionUtils
;
/**
* AOP Alliance <code>MethodInterceptor</code> that processes method invocations
* asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}.
* Typically used with the {@link org.springframework.context.task.Async} annotation.
*
* <p>In terms of target method signatures, any parameter types are supported.
* However, the return type is constrained to either <code>void</code> or
* <code>java.util.concurrent.Future</code>. In the latter case, the Future handle
* returned from the proxy will be an actual asynchronous Future that can be used
* to track the result of the asynchronous method execution. However, since the
* target method needs to implement the same signature, it will have to return
* a temporary Future handle that just passes the return value through
* (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult}
* or EJB 3.1's <code>javax.ejb.AsyncResult</code>).
*
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.scheduling.annotation.Async
* @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor
*/
public
class
AsyncExecutionInterceptor
implements
MethodInterceptor
,
Ordered
{
private
final
AsyncTaskExecutor
asyncExecutor
;
/**
* Create a new AsyncExecutionInterceptor.
* @param asyncExecutor the Spring AsyncTaskExecutor to delegate to
*/
public
AsyncExecutionInterceptor
(
AsyncTaskExecutor
asyncExecutor
)
{
Assert
.
notNull
(
asyncExecutor
,
"TaskExecutor must not be null"
);
this
.
asyncExecutor
=
asyncExecutor
;
}
/**
* Create a new AsyncExecutionInterceptor.
* @param asyncExecutor the <code>java.util.concurrent</code> Executor
* to delegate to (typically a {@link java.util.concurrent.ExecutorService}
*/
public
AsyncExecutionInterceptor
(
Executor
asyncExecutor
)
{
this
.
asyncExecutor
=
new
TaskExecutorAdapter
(
asyncExecutor
);
}
public
Object
invoke
(
final
MethodInvocation
invocation
)
throws
Throwable
{
Future
result
=
this
.
asyncExecutor
.
submit
(
new
Callable
<
Object
>()
{
public
Object
call
()
throws
Exception
{
try
{
Object
result
=
invocation
.
proceed
();
if
(
result
instanceof
Future
)
{
return
((
Future
)
result
).
get
();
}
}
catch
(
Throwable
ex
)
{
ReflectionUtils
.
rethrowException
(
ex
);
}
return
null
;
}
});
if
(
Future
.
class
.
isAssignableFrom
(
invocation
.
getMethod
().
getReturnType
()))
{
return
result
;
}
else
{
return
null
;
}
}
public
int
getOrder
()
{
return
Ordered
.
HIGHEST_PRECEDENCE
;
}
}
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Async.java
0 → 100644
浏览文件 @
777a104d
/*
* 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 as a candidate for <i>asynchronous</i> execution.
* Can also be used at the type level, in which case all of the type's methods are
* considered as asynchronous.
*
* <p>In terms of target method signatures, any parameter types are supported.
* However, the return type is constrained to either <code>void</code> or
* <code>java.util.concurrent.Future</code>. In the latter case, the Future handle
* returned from the proxy will be an actual asynchronous Future that can be used
* to track the result of the asynchronous method execution. However, since the
* target method needs to implement the same signature, it will have to return
* a temporary Future handle that just passes the return value through: e.g.
* Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>.
*
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.aop.interceptor.AsyncExecutionInterceptor
* @see AsyncAnnotationAdvisor
*/
@Target
({
ElementType
.
TYPE
,
ElementType
.
METHOD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
public
@interface
Async
{
}
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java
0 → 100644
浏览文件 @
777a104d
/*
* 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.Annotation
;
import
java.util.HashSet
;
import
java.util.LinkedHashSet
;
import
java.util.Set
;
import
java.util.concurrent.Executor
;
import
org.aopalliance.aop.Advice
;
import
org.springframework.aop.Pointcut
;
import
org.springframework.aop.interceptor.AsyncExecutionInterceptor
;
import
org.springframework.aop.support.AbstractPointcutAdvisor
;
import
org.springframework.aop.support.ComposablePointcut
;
import
org.springframework.aop.support.annotation.AnnotationMatchingPointcut
;
import
org.springframework.core.task.AsyncTaskExecutor
;
import
org.springframework.core.task.SimpleAsyncTaskExecutor
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ClassUtils
;
/**
* Advisor that activates asynchronous method execution through the {@link Async}
* annotation. This annotation can be used at the method and type level in
* implementation classes as well as in service interfaces.
*
* <p>This advisor detects the EJB 3.1 <code>javax.ejb.Asynchronous</code>
* annotation as well, treating it exactly like Spring's own <code>Async</code>.
* Furthermore, a custom async annotation type may get specified through the
* {@link #setAsyncAnnotationType "asyncAnnotationType"} property.
*
* @author Juergen Hoeller
* @since 3.0
* @see PersistenceExceptionTranslationAdvisor
* @see org.springframework.stereotype.Repository
* @see org.springframework.dao.DataAccessException
* @see org.springframework.dao.support.PersistenceExceptionTranslator
*/
public
class
AsyncAnnotationAdvisor
extends
AbstractPointcutAdvisor
{
private
Advice
advice
;
private
Pointcut
pointcut
;
/**
* Create a new ConcurrencyAnnotationBeanPostProcessor for bean-style configuration.
*/
public
AsyncAnnotationAdvisor
()
{
this
(
new
SimpleAsyncTaskExecutor
());
}
/**
* Create a new ConcurrencyAnnotationBeanPostProcessor for the given task executor.
* @param executor the task executor to use for asynchronous methods
*/
@SuppressWarnings
(
"unchecked"
)
public
AsyncAnnotationAdvisor
(
Executor
executor
)
{
Set
<
Class
<?
extends
Annotation
>>
asyncAnnotationTypes
=
new
LinkedHashSet
<
Class
<?
extends
Annotation
>>(
2
);
asyncAnnotationTypes
.
add
(
Async
.
class
);
try
{
asyncAnnotationTypes
.
add
(
ClassUtils
.
forName
(
"javax.ejb.Asynchronous"
,
AsyncAnnotationAdvisor
.
class
.
getClassLoader
()));
}
catch
(
ClassNotFoundException
ex
)
{
// If EJB 3.1 API not present, simply ignore.
}
this
.
advice
=
buildAdvice
(
executor
);
this
.
pointcut
=
buildPointcut
(
asyncAnnotationTypes
);
}
/**
* Specify the task executor to use for asynchronous methods.
*/
public
void
setTaskExecutor
(
Executor
executor
)
{
this
.
advice
=
buildAdvice
(
executor
);
}
/**
* Set the 'async' annotation type.
* <p>The default async annotation type is the {@link Async} annotation, as well
* as the EJB 3.1 <code>javax.ejb.Asynchronous</code> annotation (if present).
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate that a method is to
* be executed asynchronously.
* @param asyncAnnotationType the desired annotation type
*/
public
void
setAsyncAnnotationType
(
Class
<?
extends
Annotation
>
asyncAnnotationType
)
{
Assert
.
notNull
(
asyncAnnotationType
,
"'asyncAnnotationType' must not be null"
);
Set
<
Class
<?
extends
Annotation
>>
asyncAnnotationTypes
=
new
HashSet
<
Class
<?
extends
Annotation
>>();
asyncAnnotationTypes
.
add
(
asyncAnnotationType
);
this
.
pointcut
=
buildPointcut
(
asyncAnnotationTypes
);
}
public
Advice
getAdvice
()
{
return
this
.
advice
;
}
public
Pointcut
getPointcut
()
{
return
this
.
pointcut
;
}
protected
Advice
buildAdvice
(
Executor
executor
)
{
if
(
executor
instanceof
AsyncTaskExecutor
)
{
return
new
AsyncExecutionInterceptor
((
AsyncTaskExecutor
)
executor
);
}
else
{
return
new
AsyncExecutionInterceptor
(
executor
);
}
}
/**
* Calculate a pointcut for the given target class, if any.
* @param targetClass the class to introspect
* @return the applicable Pointcut object, or <code>null</code> if none
*/
protected
Pointcut
buildPointcut
(
Set
<
Class
<?
extends
Annotation
>>
asyncAnnotationTypes
)
{
ComposablePointcut
result
=
null
;
for
(
Class
<?
extends
Annotation
>
asyncAnnotationType
:
asyncAnnotationTypes
)
{
Pointcut
cpc
=
new
AnnotationMatchingPointcut
(
asyncAnnotationType
,
true
);
Pointcut
mpc
=
new
AnnotationMatchingPointcut
(
null
,
asyncAnnotationType
);
if
(
result
==
null
)
{
result
=
new
ComposablePointcut
(
cpc
).
union
(
mpc
);
}
else
{
result
.
union
(
cpc
).
union
(
mpc
);
}
}
return
result
;
}
}
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java
0 → 100644
浏览文件 @
777a104d
/*
* 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
java.util.concurrent.TimeUnit
;
/**
* A pass-through <code>Future</code> handle that can be used for method signatures
* which are declared with a Future return type for asynchronous execution.
*
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.scheduling.annotation.Async
*/
public
class
AsyncResult
<
V
>
implements
Future
<
V
>
{
private
final
V
value
;
/**
* Create a new AsyncResult holder.
* @param value the value to pass through
*/
public
AsyncResult
(
V
value
)
{
this
.
value
=
value
;
}
public
boolean
cancel
(
boolean
mayInterruptIfRunning
)
{
return
false
;
}
public
boolean
isCancelled
()
{
return
false
;
}
public
boolean
isDone
()
{
return
true
;
}
public
V
get
()
{
return
this
.
value
;
}
public
V
get
(
long
timeout
,
TimeUnit
unit
)
{
return
this
.
value
;
}
}
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/package.html
0 → 100644
浏览文件 @
777a104d
<html>
<body>
JDK 1.5+ annotation for asynchronous method execution.
</body>
</html>
org.springframework.context/src/test/java/example/scannable/AutowiredQualifierFooService.java
浏览文件 @
777a104d
/*
* Copyright 2002-200
7
the original author or authors.
* Copyright 2002-200
9
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.
...
...
@@ -16,13 +16,16 @@
package
example.scannable
;
import
java.util.concurrent.Future
;
import
javax.annotation.PostConstruct
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.scheduling.annotation.AsyncResult
;
/**
* @author Mark Fisher
* @author Juergen Hoeller
*/
public
class
AutowiredQualifierFooService
implements
FooService
{
...
...
@@ -44,6 +47,10 @@ public class AutowiredQualifierFooService implements FooService {
return
this
.
fooDao
.
findFoo
(
id
);
}
public
Future
<
String
>
asyncFoo
(
int
id
)
{
return
new
AsyncResult
<
String
>(
this
.
fooDao
.
findFoo
(
id
));
}
public
boolean
isInitCalled
()
{
return
this
.
initCalled
;
}
...
...
org.springframework.context/src/test/java/example/scannable/FooService.java
浏览文件 @
777a104d
/*
* Copyright 2002-200
7
the original author or authors.
* Copyright 2002-200
9
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.
...
...
@@ -16,6 +16,10 @@
package
example.scannable
;
import
java.util.concurrent.Future
;
import
org.springframework.scheduling.annotation.Async
;
/**
* @author Mark Fisher
* @author Juergen Hoeller
...
...
@@ -23,7 +27,10 @@ package example.scannable;
public
interface
FooService
{
String
foo
(
int
id
);
@Async
Future
<
String
>
asyncFoo
(
int
id
);
boolean
isInitCalled
();
}
org.springframework.context/src/test/java/example/scannable/FooServiceImpl.java
浏览文件 @
777a104d
/*
* Copyright 2002-200
7
the original author or authors.
* Copyright 2002-200
9
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.
...
...
@@ -17,7 +17,7 @@
package
example.scannable
;
import
java.util.List
;
import
java.util.concurrent.Future
;
import
javax.annotation.PostConstruct
;
import
org.springframework.beans.factory.BeanFactory
;
...
...
@@ -30,7 +30,9 @@ import org.springframework.context.MessageSource;
import
org.springframework.context.support.AbstractApplicationContext
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.core.io.support.ResourcePatternResolver
;
import
org.springframework.scheduling.annotation.AsyncResult
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.Assert
;
/**
* @author Mark Fisher
...
...
@@ -73,6 +75,12 @@ public class FooServiceImpl implements FooService {
return
this
.
fooDao
.
findFoo
(
id
);
}
public
Future
<
String
>
asyncFoo
(
int
id
)
{
System
.
out
.
println
(
Thread
.
currentThread
().
getName
());
Assert
.
state
(
ServiceInvocationCounter
.
getThreadLocalCount
()
!=
null
,
"Thread-local counter not exposed"
);
return
new
AsyncResult
<
String
>(
this
.
fooDao
.
findFoo
(
id
));
}
public
boolean
isInitCalled
()
{
return
this
.
initCalled
;
}
...
...
org.springframework.context/src/test/java/example/scannable/ScopedProxyTestBean.java
浏览文件 @
777a104d
/*
* Copyright 2002-200
7
the original author or authors.
* Copyright 2002-200
9
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.
...
...
@@ -16,7 +16,10 @@
package
example.scannable
;
import
java.util.concurrent.Future
;
import
org.springframework.context.annotation.Scope
;
import
org.springframework.scheduling.annotation.AsyncResult
;
/**
* @author Mark Fisher
...
...
@@ -29,6 +32,10 @@ public class ScopedProxyTestBean implements FooService {
return
"bar"
;
}
public
Future
<
String
>
asyncFoo
(
int
id
)
{
return
new
AsyncResult
<
String
>(
"bar"
);
}
public
boolean
isInitCalled
()
{
return
false
;
}
...
...
org.springframework.context/src/test/java/example/scannable/ServiceInvocationCounter.java
浏览文件 @
777a104d
...
...
@@ -31,16 +31,25 @@ public class ServiceInvocationCounter {
private
int
useCount
;
private
static
final
ThreadLocal
<
Integer
>
threadLocalCount
=
new
ThreadLocal
<
Integer
>();
@Pointcut
(
"execution(* example.scannable.FooService+.*(..))"
)
public
void
serviceExecution
()
{}
@Before
(
"serviceExecution()"
)
public
void
countUse
()
{
this
.
useCount
++;
this
.
threadLocalCount
.
set
(
this
.
useCount
);
System
.
out
.
println
(
""
);
}
public
int
getCount
()
{
return
this
.
useCount
;
}
public
static
Integer
getThreadLocalCount
()
{
return
threadLocalCount
.
get
();
}
}
org.springframework.context/src/test/java/org/springframework/context/annotation/ClassPathBeanDefinitionScannerTests.java
浏览文件 @
777a104d
/*
* Copyright 2002-200
8
the original author or authors.
* Copyright 2002-200
9
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.
...
...
@@ -16,9 +16,13 @@
package
org.springframework.context.annotation
;
import
static
org
.
junit
.
Assert
.*;
import
example.scannable.CustomComponent
;
import
example.scannable.FooService
;
import
example.scannable.FooServiceImpl
;
import
example.scannable.NamedStubDao
;
import
example.scannable.StubFooDao
;
import
org.aspectj.lang.annotation.Aspect
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Test
;
import
org.springframework.beans.TestBean
;
...
...
@@ -35,12 +39,6 @@ import org.springframework.core.type.filter.AnnotationTypeFilter;
import
org.springframework.core.type.filter.AssignableTypeFilter
;
import
org.springframework.stereotype.Component
;
import
example.scannable.CustomComponent
;
import
example.scannable.FooService
;
import
example.scannable.FooServiceImpl
;
import
example.scannable.NamedStubDao
;
import
example.scannable.StubFooDao
;
/**
* @author Mark Fisher
* @author Juergen Hoeller
...
...
@@ -64,8 +62,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
"thoreau"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -119,8 +117,8 @@ public class ClassPathBeanDefinitionScannerTests {
}
catch
(
IllegalStateException
ex
)
{
// expected
assertTrue
(
ex
.
getMessage
().
indexOf
(
"stubFooDao"
)
!=
-
1
);
assertTrue
(
ex
.
getMessage
().
indexOf
(
StubFooDao
.
class
.
getName
())
!=
-
1
);
assertTrue
(
ex
.
getMessage
().
contains
(
"stubFooDao"
)
);
assertTrue
(
ex
.
getMessage
().
contains
(
StubFooDao
.
class
.
getName
())
);
}
}
...
...
@@ -194,8 +192,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertEquals
(
4
,
beanCount
);
assertTrue
(
context
.
containsBean
(
"messageBean"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -212,8 +210,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertFalse
(
context
.
containsBean
(
"myNamedComponent"
));
assertFalse
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -230,8 +228,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedComponent"
));
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -247,8 +245,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedComponent"
));
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -264,8 +262,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedComponent"
));
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -282,8 +280,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedComponent"
));
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertFalse
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertFalse
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertFalse
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertFalse
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -300,8 +298,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedComponent"
));
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
@@ -318,8 +316,8 @@ public class ClassPathBeanDefinitionScannerTests {
assertTrue
(
context
.
containsBean
(
"myNamedComponent"
));
assertTrue
(
context
.
containsBean
(
"myNamedDao"
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME
));
assertTrue
(
context
.
containsBean
(
AnnotationConfigUtils
.
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME
));
}
@Test
...
...
org.springframework.context/src/test/java/org/springframework/context/annotation/SimpleConfigTests.java
浏览文件 @
777a104d
/*
* Copyright 2002-200
7
the original author or authors.
* Copyright 2002-200
9
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.
...
...
@@ -16,38 +16,44 @@
package
org.springframework.context.annotation
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.junit.Test
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.FutureTask
;
import
example.scannable.FooService
;
import
example.scannable.ServiceInvocationCounter
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Test
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
/**
* @author Mark Fisher
* @author Juergen Hoeller
*/
public
class
SimpleConfigTests
{
@Test
public
void
testFooService
()
throws
Exception
{
ClassPathXmlApplicationContext
ctx
=
new
ClassPathXmlApplicationContext
(
getConfigLocations
(),
getClass
());
FooService
fooService
=
(
FooService
)
ctx
.
getBean
(
"fooServiceImpl"
);
ServiceInvocationCounter
serviceInvocationCounter
=
(
ServiceInvocationCounter
)
ctx
.
getBean
(
"serviceInvocationCounter"
);
FooService
fooService
=
ctx
.
getBean
(
"fooServiceImpl"
,
FooService
.
class
);
ServiceInvocationCounter
serviceInvocationCounter
=
ctx
.
getBean
(
"serviceInvocationCounter"
,
ServiceInvocationCounter
.
class
);
String
value
=
fooService
.
foo
(
1
);
assertEquals
(
"bar"
,
value
);
assertEquals
(
1
,
serviceInvocationCounter
.
getCount
());
fooService
.
foo
(
1
);
Future
future
=
fooService
.
asyncFoo
(
1
);
assertTrue
(
future
instanceof
FutureTask
);
assertEquals
(
"bar"
,
future
.
get
());
assertEquals
(
2
,
serviceInvocationCounter
.
getCount
());
fooService
.
foo
(
1
);
assertEquals
(
3
,
serviceInvocationCounter
.
getCount
());
}
public
String
[]
getConfigLocations
()
{
return
new
String
[]
{
"simpleConfigTests.xml"
};
}
}
org.springframework.context/src/test/java/org/springframework/context/annotation/simpleConfigTests.xml
浏览文件 @
777a104d
...
...
@@ -8,13 +8,21 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>
<context:annotation-config/>
<aop:aspectj-autoproxy/>
<bean
class=
"org.springframework.scheduling.annotation.AsyncAnnotationAdvisor"
>
<!--
<property name="taskExecutor">
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"/>
</property>
-->
</bean>
<bean
id=
"fooServiceImpl"
class=
"example.scannable.FooServiceImpl"
/>
<bean
id=
"serviceInvocationCounter"
class=
"example.scannable.ServiceInvocationCounter"
/>
<bean
class=
"example.scannable.StubFooDao"
/>
</beans>
org.springframework.context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java
0 → 100644
浏览文件 @
777a104d
/*
* 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
));
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录