Skip to content

Commit b4cda62

Browse files
committed
Break cycle caused by JndiDataSourceAutoConfiguration
There's a long cycle when Spring Data REST, Data JPA and Actuator are used in an app that retrieves its DataSource from JNDI. The cycle is: - WebMvcAutoConfiguration - HttpMessageConverters - MappingJackson2HttpMessageConverter (needs an ObjectMapper) - SpringBootRepositoryRestMvcConfiguration - ObjectMapper - RepositoryResourceMappings (part of a custom Jackson module) - Repositories - EntityManagerFactory (Triggered by application's Spring Data JPA repository) - HibernateJpaAutoConfiguration - JndiDataSourceAutoConfiguration - MBeanExporter (Used to prevent export of DataSource MBean that's already in JMX) - EndpointMBeanExportAutoConfiguration - ObjectMapper (Used to format JSON produced by the exported endpoints) Spring Data Rest caused the ObjectMapper to depend on JPA. JPA depends on the DataSource. JnidDataSourceAutoConfiguration depends on the MBeanExporter. Actuator's MBeanExporter requires an ObjectMapper to produce JSON strings. This commit breaks the cycle by making JndiDataSourceAutoConfiguration access the MBeanExporter lazily. Rather than using `@Lazy`. which does not work with `@Autowired(required=false)`, the application context is injected and the MBeanExporter is retrieved manually when it is needed. Closes gh-4980
1 parent d05f941 commit b4cda62

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818

1919
import javax.sql.DataSource;
2020

21+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2122
import org.springframework.beans.factory.annotation.Autowired;
2223
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
2324
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2425
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2526
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2627
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2728
import org.springframework.boot.context.properties.EnableConfigurationProperties;
29+
import org.springframework.context.ApplicationContext;
2830
import org.springframework.context.annotation.Bean;
2931
import org.springframework.context.annotation.Configuration;
3032
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@@ -48,8 +50,8 @@
4850
@EnableConfigurationProperties(DataSourceProperties.class)
4951
public class JndiDataSourceAutoConfiguration {
5052

51-
@Autowired(required = false)
52-
private MBeanExporter mbeanExporter;
53+
@Autowired
54+
private ApplicationContext context;
5355

5456
@Bean(destroyMethod = "")
5557
@ConditionalOnMissingBean
@@ -61,8 +63,14 @@ public DataSource dataSource(DataSourceProperties properties) {
6163
}
6264

6365
private void excludeMBeanIfNecessary(Object candidate, String beanName) {
64-
if (this.mbeanExporter != null && JmxUtils.isMBean(candidate.getClass())) {
65-
this.mbeanExporter.addExcludedBean(beanName);
66+
try {
67+
MBeanExporter mbeanExporter = this.context.getBean(MBeanExporter.class);
68+
if (JmxUtils.isMBean(candidate.getClass())) {
69+
mbeanExporter.addExcludedBean(beanName);
70+
}
71+
}
72+
catch (NoSuchBeanDefinitionException ex) {
73+
// No exporter. Exclusion is unnecessary
6674
}
6775
}
6876

0 commit comments

Comments
 (0)