Skip to content

Commit 419f92d

Browse files
committed
Tune @ConditionalOnMissingBean for interface-based back off
Previously, a number of usages of @ConditionalOnMissingBean prevented a bean that implements an auto-configured bean's "main" interface from causing the auto-configuration of the bean to back off. This would happen when @ConditionalOnMissingBean did not specify a type, the @bean method returned the bean's concrete type, and that concreate type implements a "main" interface. This commit updates such usages of @ConditionalOnMissingBean to specify the "main" interface as the type of the bean that must be missing. This will allow, for example, the auto-configured MongoTemplate bean to back off when a MongoOperations bean is defined. Fixes gh-18101
1 parent d89adfa commit 419f92d

13 files changed

+28
-15
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
2929
import org.springframework.amqp.rabbit.core.RabbitAdmin;
3030
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
31+
import org.springframework.amqp.rabbit.core.RabbitOperations;
3132
import org.springframework.amqp.rabbit.core.RabbitTemplate;
3233
import org.springframework.amqp.support.converter.MessageConverter;
3334
import org.springframework.beans.factory.ObjectProvider;
@@ -165,7 +166,7 @@ public RabbitTemplateConfiguration(RabbitProperties properties,
165166

166167
@Bean
167168
@ConditionalOnSingleCandidate(ConnectionFactory.class)
168-
@ConditionalOnMissingBean
169+
@ConditionalOnMissingBean(RabbitOperations.class)
169170
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
170171
PropertyMapper map = PropertyMapper.get();
171172
RabbitTemplate template = new RabbitTemplate(connectionFactory);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.data.cassandra.config.CassandraSessionFactoryBean;
4343
import org.springframework.data.cassandra.config.SchemaAction;
4444
import org.springframework.data.cassandra.core.CassandraAdminOperations;
45+
import org.springframework.data.cassandra.core.CassandraOperations;
4546
import org.springframework.data.cassandra.core.CassandraTemplate;
4647
import org.springframework.data.cassandra.core.convert.CassandraConverter;
4748
import org.springframework.data.cassandra.core.convert.CassandraCustomConversions;
@@ -125,7 +126,7 @@ public CassandraSessionFactoryBean cassandraSession(CassandraConverter converter
125126
}
126127

127128
@Bean
128-
@ConditionalOnMissingBean
129+
@ConditionalOnMissingBean(CassandraOperations.class)
129130
public CassandraTemplate cassandraTemplate(Session session, CassandraConverter converter) throws Exception {
130131
return new CassandraTemplate(session, converter);
131132
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/cassandra/CassandraReactiveDataAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.context.annotation.Configuration;
3030
import org.springframework.data.cassandra.ReactiveSession;
3131
import org.springframework.data.cassandra.ReactiveSessionFactory;
32+
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
3233
import org.springframework.data.cassandra.core.ReactiveCassandraTemplate;
3334
import org.springframework.data.cassandra.core.convert.CassandraConverter;
3435
import org.springframework.data.cassandra.core.cql.session.DefaultBridgedReactiveSession;
@@ -60,7 +61,7 @@ public ReactiveSessionFactory reactiveCassandraSessionFactory(ReactiveSession re
6061
}
6162

6263
@Bean
63-
@ConditionalOnMissingBean
64+
@ConditionalOnMissingBean(ReactiveCassandraOperations.class)
6465
public ReactiveCassandraTemplate reactiveCassandraTemplate(ReactiveSession reactiveCassandraSession,
6566
CassandraConverter converter) {
6667
return new ReactiveCassandraTemplate(reactiveCassandraSession, converter);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2626
import org.springframework.context.annotation.Bean;
2727
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
2829
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
2930
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
3031
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
@@ -49,7 +50,7 @@
4950
public class ElasticsearchDataAutoConfiguration {
5051

5152
@Bean
52-
@ConditionalOnMissingBean
53+
@ConditionalOnMissingBean(ElasticsearchOperations.class)
5354
@ConditionalOnBean(Client.class)
5455
public ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) {
5556
try {

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryDependentConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929
import org.springframework.dao.DataAccessException;
3030
import org.springframework.dao.support.PersistenceExceptionTranslator;
3131
import org.springframework.data.mongodb.MongoDbFactory;
32+
import org.springframework.data.mongodb.core.MongoOperations;
3233
import org.springframework.data.mongodb.core.MongoTemplate;
3334
import org.springframework.data.mongodb.core.convert.DbRefResolver;
3435
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
3536
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
3637
import org.springframework.data.mongodb.core.convert.MongoConverter;
3738
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
3839
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
40+
import org.springframework.data.mongodb.gridfs.GridFsOperations;
3941
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
4042
import org.springframework.util.Assert;
4143
import org.springframework.util.StringUtils;
@@ -56,7 +58,7 @@ class MongoDbFactoryDependentConfiguration {
5658
}
5759

5860
@Bean
59-
@ConditionalOnMissingBean
61+
@ConditionalOnMissingBean(MongoOperations.class)
6062
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) {
6163
return new MongoTemplate(mongoDbFactory, converter);
6264
}
@@ -72,7 +74,7 @@ public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, Mongo
7274
}
7375

7476
@Bean
75-
@ConditionalOnMissingBean
77+
@ConditionalOnMissingBean(GridFsOperations.class)
7678
public GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate) {
7779
return new GridFsTemplate(new GridFsMongoDbFactory(mongoDbFactory, this.properties),
7880
mongoTemplate.getConverter());

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.context.annotation.Configuration;
3131
import org.springframework.context.annotation.Import;
3232
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
33+
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
3334
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
3435
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
3536
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
@@ -73,7 +74,7 @@ public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClie
7374
}
7475

7576
@Bean
76-
@ConditionalOnMissingBean
77+
@ConditionalOnMissingBean(ReactiveMongoOperations.class)
7778
public ReactiveMongoTemplate reactiveMongoTemplate(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory,
7879
MongoConverter converter) {
7980
return new ReactiveMongoTemplate(reactiveMongoDatabaseFactory, converter);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
import org.springframework.context.annotation.Bean;
3535
import org.springframework.context.annotation.Configuration;
3636
import org.springframework.context.annotation.Import;
37+
import org.springframework.jms.core.JmsMessageOperations;
3738
import org.springframework.jms.core.JmsMessagingTemplate;
39+
import org.springframework.jms.core.JmsOperations;
3840
import org.springframework.jms.core.JmsTemplate;
3941
import org.springframework.jms.support.converter.MessageConverter;
4042
import org.springframework.jms.support.destination.DestinationResolver;
@@ -71,7 +73,7 @@ public JmsTemplateConfiguration(JmsProperties properties,
7173
}
7274

7375
@Bean
74-
@ConditionalOnMissingBean
76+
@ConditionalOnMissingBean(JmsOperations.class)
7577
@ConditionalOnSingleCandidate(ConnectionFactory.class)
7678
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
7779
PropertyMapper map = PropertyMapper.get();
@@ -104,7 +106,7 @@ private void mapTemplateProperties(Template properties, JmsTemplate template) {
104106
protected static class MessagingTemplateConfiguration {
105107

106108
@Bean
107-
@ConditionalOnMissingBean
109+
@ConditionalOnMissingBean(JmsMessageOperations.class)
108110
@ConditionalOnSingleCandidate(JmsTemplate.class)
109111
public JmsMessagingTemplate jmsMessagingTemplate(JmsTemplate jmsTemplate) {
110112
return new JmsMessagingTemplate(jmsTemplate);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
public class JooqAutoConfiguration {
6565

6666
@Bean
67-
@ConditionalOnMissingBean
67+
@ConditionalOnMissingBean(ConnectionProvider.class)
6868
public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource) {
6969
return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
7070
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailSenderPropertiesConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.context.annotation.Bean;
2525
import org.springframework.context.annotation.Configuration;
2626
import org.springframework.mail.MailSender;
27+
import org.springframework.mail.javamail.JavaMailSender;
2728
import org.springframework.mail.javamail.JavaMailSenderImpl;
2829

2930
/**
@@ -44,7 +45,7 @@ class MailSenderPropertiesConfiguration {
4445
}
4546

4647
@Bean
47-
@ConditionalOnMissingBean
48+
@ConditionalOnMissingBean(JavaMailSender.class)
4849
public JavaMailSenderImpl mailSender() {
4950
JavaMailSenderImpl sender = new JavaMailSenderImpl();
5051
applyProperties(sender);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/sendgrid/SendGridAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.sendgrid.Client;
2020
import com.sendgrid.SendGrid;
21+
import com.sendgrid.SendGridAPI;
2122
import org.apache.http.HttpHost;
2223
import org.apache.http.impl.client.HttpClientBuilder;
2324

@@ -50,7 +51,7 @@ public SendGridAutoConfiguration(SendGridProperties properties) {
5051
}
5152

5253
@Bean
53-
@ConditionalOnMissingBean
54+
@ConditionalOnMissingBean(SendGridAPI.class)
5455
public SendGrid sendGrid() {
5556
if (this.properties.isProxyConfigured()) {
5657
HttpHost proxy = new HttpHost(this.properties.getProxy().getHost(), this.properties.getProxy().getPort());

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.thymeleaf.dialect.IDialect;
3030
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
3131
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
32+
import org.thymeleaf.spring5.ISpringTemplateEngine;
3233
import org.thymeleaf.spring5.ISpringWebFluxTemplateEngine;
3334
import org.thymeleaf.spring5.SpringTemplateEngine;
3435
import org.thymeleaf.spring5.SpringWebFluxTemplateEngine;
@@ -147,7 +148,7 @@ public ThymeleafDefaultConfiguration(ThymeleafProperties properties,
147148
}
148149

149150
@Bean
150-
@ConditionalOnMissingBean
151+
@ConditionalOnMissingBean(ISpringTemplateEngine.class)
151152
public SpringTemplateEngine templateEngine() {
152153
SpringTemplateEngine engine = new SpringTemplateEngine();
153154
engine.setEnableSpringELCompiler(this.properties.isEnableSpringElCompiler());

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.transaction.PlatformTransactionManager;
3636
import org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration;
3737
import org.springframework.transaction.annotation.EnableTransactionManagement;
38+
import org.springframework.transaction.support.TransactionOperations;
3839
import org.springframework.transaction.support.TransactionTemplate;
3940

4041
/**
@@ -69,7 +70,7 @@ public TransactionTemplateConfiguration(PlatformTransactionManager transactionMa
6970
}
7071

7172
@Bean
72-
@ConditionalOnMissingBean
73+
@ConditionalOnMissingBean(TransactionOperations.class)
7374
public TransactionTemplate transactionTemplate() {
7475
return new TransactionTemplate(this.transactionManager);
7576
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static class DefaultErrorViewResolverConfiguration {
140140

141141
@Bean
142142
@ConditionalOnBean(DispatcherServlet.class)
143-
@ConditionalOnMissingBean
143+
@ConditionalOnMissingBean(ErrorViewResolver.class)
144144
public DefaultErrorViewResolver conventionErrorViewResolver() {
145145
return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties);
146146
}

0 commit comments

Comments
 (0)