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
This commit is contained in:
parent
d05f94170b
commit
b4cda625c4
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.jdbc;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
|
@ -25,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
@ -48,8 +50,8 @@ import org.springframework.jmx.support.JmxUtils;
|
|||
@EnableConfigurationProperties(DataSourceProperties.class)
|
||||
public class JndiDataSourceAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private MBeanExporter mbeanExporter;
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Bean(destroyMethod = "")
|
||||
@ConditionalOnMissingBean
|
||||
|
@ -61,8 +63,14 @@ public class JndiDataSourceAutoConfiguration {
|
|||
}
|
||||
|
||||
private void excludeMBeanIfNecessary(Object candidate, String beanName) {
|
||||
if (this.mbeanExporter != null && JmxUtils.isMBean(candidate.getClass())) {
|
||||
this.mbeanExporter.addExcludedBean(beanName);
|
||||
try {
|
||||
MBeanExporter mbeanExporter = this.context.getBean(MBeanExporter.class);
|
||||
if (JmxUtils.isMBean(candidate.getClass())) {
|
||||
mbeanExporter.addExcludedBean(beanName);
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// No exporter. Exclusion is unnecessary
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue