From b6786115df07ef6199930d02b000208d1372c205 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Fri, 3 Jan 2025 13:18:31 +0800 Subject: [PATCH] Ignore BeanNotOfRequiredTypeException as well as NoSuchBeanDefinitionException Closes GH-34187 --- .../interceptor/TransactionAspectSupport.java | 6 +- .../EnableTransactionManagementTests.java | 72 ++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java index f1c2c32a60c7..832092057606 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -31,6 +31,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.BeanNotOfRequiredTypeException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils; @@ -81,6 +82,7 @@ * @author Mark Paluch * @author Sebastien Deleuze * @author Enric Sala + * @author Yanming Zhou * @since 1.1 * @see PlatformTransactionManager * @see ReactiveTransactionManager @@ -506,7 +508,7 @@ else if (targetClass != null) { try { return determineQualifiedTransactionManager(this.beanFactory, typeQualifier); } - catch (NoSuchBeanDefinitionException ex) { + catch (NoSuchBeanDefinitionException | BeanNotOfRequiredTypeException ex) { // Consider type qualifier as optional, proceed with regular resolution below. } } diff --git a/spring-tx/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementTests.java b/spring-tx/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementTests.java index add722ae6854..1ca6d94c8664 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -58,6 +58,7 @@ * @author Juergen Hoeller * @author Stephane Nicoll * @author Sam Brannen + * @author Yanming Zhou * @since 3.1 */ class EnableTransactionManagementTests { @@ -287,6 +288,34 @@ void gh24291TransactionManagerViaQualifierAnnotation() { ctx.close(); } + @Test + void transactionManagerViaQualifierAnnotationWithNoSuchBeanDefinitionException() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Gh34187Config.class); + TransactionalTestBeanWithNonExistentQualifier bean = ctx.getBean(TransactionalTestBeanWithNonExistentQualifier.class); + CallCountingTransactionManager txManager = ctx.getBean("txManager", CallCountingTransactionManager.class); + + bean.findAllFoos(); + assertThat(txManager.begun).isEqualTo(1); + assertThat(txManager.commits).isEqualTo(1); + assertThat(txManager.rollbacks).isEqualTo(0); + + ctx.close(); + } + + @Test + void transactionManagerViaQualifierAnnotationWithBeanNotOfRequiredTypeException() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Gh34187Config.class); + TransactionalTestBeanWithInvalidQualifier bean = ctx.getBean(TransactionalTestBeanWithInvalidQualifier.class); + CallCountingTransactionManager txManager = ctx.getBean("txManager", CallCountingTransactionManager.class); + + bean.findAllFoos(); + assertThat(txManager.begun).isEqualTo(1); + assertThat(txManager.commits).isEqualTo(1); + assertThat(txManager.rollbacks).isEqualTo(0); + + ctx.close(); + } + @Test void spr14322AnnotationOnInterfaceWithInterfaceProxy() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Spr14322ConfigA.class); @@ -386,6 +415,17 @@ public void saveQualifiedFooWithAttributeAlias() { public static class TransactionalTestBeanSubclass extends TransactionalTestBean { } + @Service + @Qualifier("nonExistentBean") + public static class TransactionalTestBeanWithNonExistentQualifier extends TransactionalTestBean { + } + + @Service + @Qualifier("transactionalTestBeanWithInvalidQualifier") + public static class TransactionalTestBeanWithInvalidQualifier extends TransactionalTestBean { + } + + @Configuration static class PlaceholderConfig { @@ -601,6 +641,36 @@ public CallCountingTransactionManager otherTxManager() { } } + @Configuration + @EnableTransactionManagement + @Import(PlaceholderConfig.class) + static class Gh34187Config { + + @Autowired + public void initializeApp(ConfigurableApplicationContext applicationContext) { + applicationContext.getBeanFactory().registerSingleton( + "qualifiedTransactionManager", new CallCountingTransactionManager()); + applicationContext.getBeanFactory().registerAlias("qualifiedTransactionManager", "qualified"); + } + + @Bean + public TransactionalTestBeanWithNonExistentQualifier transactionalTestBeanWithNonExistentQualifier() { + return new TransactionalTestBeanWithNonExistentQualifier(); + } + + @Bean + public TransactionalTestBeanWithInvalidQualifier transactionalTestBeanWithInvalidQualifier() { + return new TransactionalTestBeanWithInvalidQualifier(); + } + + @Bean + @Primary + public CallCountingTransactionManager txManager() { + return new CallCountingTransactionManager(); + } + } + + public interface BaseTransactionalInterface {