Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
f1c7dc4f
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,发现更多精彩内容 >>
提交
f1c7dc4f
编写于
6月 18, 2015
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduced SimpleTransactionScope (analogous to SimpleThreadScope)
Issue: SPR-13085
上级
04251904
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
247 addition
and
4 deletion
+247
-4
spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java
...rg/springframework/context/support/SimpleThreadScope.java
+9
-4
spring-tx/src/main/java/org/springframework/transaction/support/SimpleTransactionScope.java
...framework/transaction/support/SimpleTransactionScope.java
+111
-0
spring-tx/src/test/java/org/springframework/transaction/support/SimpleTransactionScopeTests.java
...work/transaction/support/SimpleTransactionScopeTests.java
+127
-0
未找到文件。
spring-context/src/main/java/org/springframework/context/support/SimpleThreadScope.java
浏览文件 @
f1c7dc4f
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
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.
...
...
@@ -29,9 +29,14 @@ import org.springframework.core.NamedThreadLocal;
/**
* A simple thread-backed {@link Scope} implementation.
*
* <p><strong>Note:</strong> {@code SimpleThreadScope} <em>does not clean up
* any objects</em> associated with it. As such, it is typically preferable to
* use {@link org.springframework.web.context.request.RequestScope RequestScope}
* <p><b>NOTE:</b> This thread scope is not registered by default in common contexts.
* Instead, you need to explicitly assign it to a scope key in your setup, either through
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory#registerScope}
* or through a {@link org.springframework.beans.factory.config.CustomScopeConfigurer} bean.
*
* <p>{@code SimpleThreadScope} <em>does not clean up any objects</em> associated with it.
* As such, it is typically preferable to use
* {@link org.springframework.web.context.request.RequestScope RequestScope}
* in web environments.
*
* <p>For an implementation of a thread-based {@code Scope} with support for
...
...
spring-tx/src/main/java/org/springframework/transaction/support/SimpleTransactionScope.java
0 → 100644
浏览文件 @
f1c7dc4f
/*
* Copyright 2002-2015 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.transaction.support
;
import
java.util.HashMap
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
import
org.springframework.beans.factory.ObjectFactory
;
import
org.springframework.beans.factory.config.Scope
;
/**
* A simple transaction-backed {@link Scope} implementation, delegating to
* {@link TransactionSynchronizationManager}'s resource binding mechanism.
*
* <p><b>NOTE:</b> Like {@link org.springframework.context.support.SimpleThreadScope},
* this transaction scope is not registered by default in common contexts. Instead,
* you need to explicitly assign it to a scope key in your setup, either through
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory#registerScope}
* or through a {@link org.springframework.beans.factory.config.CustomScopeConfigurer} bean.
*
* @author Juergen Hoeller
* @since 4.2
* @see org.springframework.context.support.SimpleThreadScope
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#registerScope
* @see org.springframework.beans.factory.config.CustomScopeConfigurer
*/
public
class
SimpleTransactionScope
implements
Scope
{
@Override
public
Object
get
(
String
name
,
ObjectFactory
<?>
objectFactory
)
{
ScopedObjectsHolder
scopedObjects
=
(
ScopedObjectsHolder
)
TransactionSynchronizationManager
.
getResource
(
this
);
if
(
scopedObjects
==
null
)
{
scopedObjects
=
new
ScopedObjectsHolder
();
TransactionSynchronizationManager
.
registerSynchronization
(
new
CleanupSynchronization
());
TransactionSynchronizationManager
.
bindResource
(
this
,
scopedObjects
);
}
Object
scopedObject
=
scopedObjects
.
scopedInstances
.
get
(
name
);
if
(
scopedObject
==
null
)
{
scopedObject
=
objectFactory
.
getObject
();
scopedObjects
.
scopedInstances
.
put
(
name
,
scopedObject
);
}
return
scopedObject
;
}
@Override
public
Object
remove
(
String
name
)
{
ScopedObjectsHolder
scopedObjects
=
(
ScopedObjectsHolder
)
TransactionSynchronizationManager
.
getResource
(
this
);
if
(
scopedObjects
!=
null
)
{
scopedObjects
.
destructionCallbacks
.
remove
(
name
);
return
scopedObjects
.
scopedInstances
.
remove
(
name
);
}
else
{
return
null
;
}
}
@Override
public
void
registerDestructionCallback
(
String
name
,
Runnable
callback
)
{
ScopedObjectsHolder
scopedObjects
=
(
ScopedObjectsHolder
)
TransactionSynchronizationManager
.
getResource
(
this
);
if
(
scopedObjects
!=
null
)
{
scopedObjects
.
destructionCallbacks
.
put
(
name
,
callback
);
}
}
@Override
public
Object
resolveContextualObject
(
String
key
)
{
return
null
;
}
@Override
public
String
getConversationId
()
{
return
TransactionSynchronizationManager
.
getCurrentTransactionName
();
}
static
class
ScopedObjectsHolder
{
final
Map
<
String
,
Object
>
scopedInstances
=
new
HashMap
<
String
,
Object
>();
final
Map
<
String
,
Runnable
>
destructionCallbacks
=
new
LinkedHashMap
<
String
,
Runnable
>();
}
private
class
CleanupSynchronization
extends
TransactionSynchronizationAdapter
{
@Override
public
void
afterCompletion
(
int
status
)
{
ScopedObjectsHolder
scopedObjects
=
(
ScopedObjectsHolder
)
TransactionSynchronizationManager
.
unbindResourceIfPossible
(
SimpleTransactionScope
.
this
);
for
(
Runnable
callback
:
scopedObjects
.
destructionCallbacks
.
values
())
{
callback
.
run
();
}
}
}
}
spring-tx/src/test/java/org/springframework/transaction/support/SimpleTransactionScopeTests.java
0 → 100644
浏览文件 @
f1c7dc4f
/*
* Copyright 2002-2015 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.transaction.support
;
import
org.junit.Test
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.support.GenericBeanDefinition
;
import
org.springframework.context.support.GenericApplicationContext
;
import
org.springframework.tests.sample.beans.DerivedTestBean
;
import
org.springframework.tests.sample.beans.TestBean
;
import
static
org
.
junit
.
Assert
.*;
/**
* @author Juergen Hoeller
*/
public
class
SimpleTransactionScopeTests
{
@Test
public
void
getFromScope
()
throws
Exception
{
GenericApplicationContext
context
=
new
GenericApplicationContext
();
context
.
getBeanFactory
().
registerScope
(
"tx"
,
new
SimpleTransactionScope
());
GenericBeanDefinition
bd1
=
new
GenericBeanDefinition
();
bd1
.
setBeanClass
(
TestBean
.
class
);
bd1
.
setScope
(
"tx"
);
bd1
.
setPrimary
(
true
);
context
.
registerBeanDefinition
(
"txScopedObject1"
,
bd1
);
GenericBeanDefinition
bd2
=
new
GenericBeanDefinition
();
bd2
.
setBeanClass
(
DerivedTestBean
.
class
);
bd2
.
setScope
(
"tx"
);
context
.
registerBeanDefinition
(
"txScopedObject2"
,
bd2
);
context
.
refresh
();
try
{
context
.
getBean
(
TestBean
.
class
);
fail
(
"Should have thrown BeanCreationException"
);
}
catch
(
BeanCreationException
ex
)
{
// expected - no synchronization active
assertTrue
(
ex
.
getCause
()
instanceof
IllegalStateException
);
}
try
{
context
.
getBean
(
DerivedTestBean
.
class
);
fail
(
"Should have thrown BeanCreationException"
);
}
catch
(
BeanCreationException
ex
)
{
// expected - no synchronization active
assertTrue
(
ex
.
getCause
()
instanceof
IllegalStateException
);
}
TestBean
bean1
=
null
;
DerivedTestBean
bean2
=
null
;
DerivedTestBean
bean2a
=
null
;
DerivedTestBean
bean2b
=
null
;
TransactionSynchronizationManager
.
initSynchronization
();
try
{
bean1
=
context
.
getBean
(
TestBean
.
class
);
assertSame
(
bean1
,
context
.
getBean
(
TestBean
.
class
));
bean2
=
context
.
getBean
(
DerivedTestBean
.
class
);
assertSame
(
bean2
,
context
.
getBean
(
DerivedTestBean
.
class
));
context
.
getBeanFactory
().
destroyScopedBean
(
"txScopedObject2"
);
assertFalse
(
TransactionSynchronizationManager
.
hasResource
(
"txScopedObject2"
));
assertTrue
(
bean2
.
wasDestroyed
());
bean2a
=
context
.
getBean
(
DerivedTestBean
.
class
);
assertSame
(
bean2a
,
context
.
getBean
(
DerivedTestBean
.
class
));
assertNotSame
(
bean2
,
bean2a
);
context
.
getBeanFactory
().
getRegisteredScope
(
"tx"
).
remove
(
"txScopedObject2"
);
assertFalse
(
TransactionSynchronizationManager
.
hasResource
(
"txScopedObject2"
));
assertFalse
(
bean2a
.
wasDestroyed
());
bean2b
=
context
.
getBean
(
DerivedTestBean
.
class
);
assertSame
(
bean2b
,
context
.
getBean
(
DerivedTestBean
.
class
));
assertNotSame
(
bean2
,
bean2a
);
assertNotSame
(
bean2
,
bean2b
);
assertNotSame
(
bean2a
,
bean2b
);
}
finally
{
TransactionSynchronizationUtils
.
triggerAfterCompletion
(
TransactionSynchronization
.
STATUS_COMMITTED
);
TransactionSynchronizationManager
.
clearSynchronization
();
}
assertFalse
(
bean2a
.
wasDestroyed
());
assertTrue
(
bean2b
.
wasDestroyed
());
assertTrue
(
TransactionSynchronizationManager
.
getResourceMap
().
isEmpty
());
try
{
context
.
getBean
(
TestBean
.
class
);
fail
(
"Should have thrown IllegalStateException"
);
}
catch
(
BeanCreationException
ex
)
{
// expected - no synchronization active
assertTrue
(
ex
.
getCause
()
instanceof
IllegalStateException
);
}
try
{
context
.
getBean
(
DerivedTestBean
.
class
);
fail
(
"Should have thrown IllegalStateException"
);
}
catch
(
BeanCreationException
ex
)
{
// expected - no synchronization active
assertTrue
(
ex
.
getCause
()
instanceof
IllegalStateException
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录