gpt4 book ai didi

java - 当@ActiveProfiles ("test"时,如何忽略特定方法的 spring @Transactional 注释)

转载 作者:搜寻专家 更新时间:2023-11-01 03:34:21 26 4
gpt4 key购买 nike

我需要在集成测试期间忽略以下 @Transactional 注释。

@Service
public class MyClass {

@Transactional(propagation = Propagation.NEVER)
public void doSomething() {
// do something that once in production can not be inside a transaction (reasons are omitted)
}

}

问题是我所有的测试都是在默认情况下回滚的事务中执行的。当此方法在测试范围内运行时,我怎么能忽略此方法的 @Transactional(propagation = Propagation.NEVER) 注释 (@ActiveProfiles("test") ) 允许它在事务内执行?

最佳答案

首先,你需要排除你当前的@EnableTransactionManagement注释在您的 test 中处于 Activity 状态轮廓。您可以通过隔离 @EnableTransactionManagement 来做到这一点对排除配置文件 test 的单独配置类的注释所以它只会在 test 时被激活配置文件有效。

@EnableTransactionManagement(mode=AdviceMode.PROXY)
@Profile("!test")
public class TransactionManagementConfig {}

有了这些,我们就可以开始为您的测试配置文件构建自定义事务管理配置。首先,我们定义一个注释,将用于激活自定义事务管理(为了示例的紧凑性而删除了 javadoc 注释,有关详细信息,请参阅 EnableTransactionManagement javadoc)。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CustomTransactionManagementConfigurationSelector.class)
public @interface EnableCustomTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}

然后我们需要一个导入选择器。请注意,因为您使用的是 AdviceMode.PROXY ,我跳过了实现 ASPECTJ部分,但为了使用基于 AspectJ 的事务管理,应该类似地完成。

public class CustomTransactionManagementConfigurationSelector extends
AdviceModeImportSelector<EnableCustomTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {
AutoProxyRegistrar.class.getName(),
CustomTransactionAttributeSourceConfig.class.getName()
};
case ASPECTJ:
default:
return null;
}
}
}

最后是您可以覆盖交易属性的部分。这一个子类 ProxyTransactionManagementConfiguration对于 AdviceMode.PROXY , 你需要一个基于 AspectJTransactionManagementConfiguration 的类似实现对于 AdviceMode.ASPECTJ .随意实现您自己的逻辑,无论是对原始 AnnotationTransactionAttributeSource 的任何属性的常量覆盖将按照我的示例进行确定,或者通过为此目的引入和处理您自己的自定义注释来进行更深入的研究。

@Configuration
public class CustomTransactionAttributeSourceConfig
extends ProxyTransactionManagementConfiguration {

@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableTx = AnnotationAttributes
.fromMap(importMetadata.getAnnotationAttributes(
EnableCustomTransactionManagement.class.getName(),
false));
Assert.notNull(this.enableTx,
"@EnableCustomTransactionManagement is not present on importing class "
+ importMetadata.getClassName());
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Override
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource() {

private static final long serialVersionUID = 1L;

@Override
protected TransactionAttribute findTransactionAttribute(
Class<?> clazz) {
TransactionAttribute transactionAttribute =
super.findTransactionAttribute(clazz);
if (transactionAttribute != null) {
// implement whatever logic to override transaction attributes
// extracted from @Transactional annotation
transactionAttribute = new DefaultTransactionAttribute(
TransactionAttribute.PROPAGATION_REQUIRED);
}
return transactionAttribute;
}

@Override
protected TransactionAttribute findTransactionAttribute(
Method method) {
TransactionAttribute transactionAttribute =
super.findTransactionAttribute(method);
if (transactionAttribute != null) {
// implement whatever logic to override transaction attributes
// extracted from @Transactional annotation
transactionAttribute = new DefaultTransactionAttribute(
TransactionAttribute.PROPAGATION_REQUIRED);
}
return transactionAttribute;
}
};
}
}

最后,您需要使用绑定(bind)到 test 的配置类来启用自定义事务管理配置。简介。

@EnableCustomTransactionManagement(mode=AdviceMode.PROXY)
@Profile("test")
public class TransactionManagementTestConfig {}

希望对您有所帮助。

关于java - 当@ActiveProfiles ("test"时,如何忽略特定方法的 spring @Transactional 注释),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35902955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com