Retrieve beans from BeanFactory instead of calling local configuration class bean methods.

We now lookup beans from the BeanFactory instead of expecting a proxied arrangement of configuration class bean methods which allows using @Configuration(proxyBeanMethods = false).

Closes gh-546.
This commit is contained in:
Mark Paluch
2020-03-30 15:22:42 +02:00
parent 5c661c9d47
commit 5be0fa2868
3 changed files with 42 additions and 18 deletions

View File

@@ -60,7 +60,7 @@ import org.springframework.web.reactive.function.client.WebClient;
* @author Mark Paluch
* @since 2.0
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public abstract class AbstractReactiveVaultConfiguration
extends AbstractVaultConfiguration {
@@ -91,7 +91,7 @@ public abstract class AbstractReactiveVaultConfiguration
public ReactiveVaultTemplate reactiveVaultTemplate() {
return new ReactiveVaultTemplate(
webClientBuilder(vaultEndpointProvider(), clientHttpConnector()),
reactiveSessionManager());
getReactiveSessionManager());
}
/**
@@ -103,7 +103,7 @@ public abstract class AbstractReactiveVaultConfiguration
@Bean
@Override
public SessionManager sessionManager() {
return new ReactiveSessionManagerAdapter(reactiveSessionManager());
return new ReactiveSessionManagerAdapter(getReactiveSessionManager());
}
/**
@@ -121,7 +121,7 @@ public abstract class AbstractReactiveVaultConfiguration
WebClient webClient = ReactiveVaultClients.createWebClient(vaultEndpoint(),
clientHttpConnector());
return new ReactiveLifecycleAwareSessionManager(vaultTokenSupplier(),
threadPoolTaskScheduler(), webClient);
getVaultThreadPoolTaskScheduler(), webClient);
}
/**
@@ -173,6 +173,11 @@ public abstract class AbstractReactiveVaultConfiguration
return ClientHttpConnectorFactory.create(clientOptions(), sslConfiguration());
}
private ReactiveSessionManager getReactiveSessionManager() {
return getBeanFactory().getBean("reactiveSessionManager",
ReactiveSessionManager.class);
}
/**
* Simple {@link SessionManager} adapter using a {@link ReactiveSessionManager} to
* obtain tokens.

View File

@@ -16,6 +16,7 @@
package org.springframework.vault.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
@@ -33,7 +34,6 @@ import org.springframework.vault.authentication.SessionManager;
import org.springframework.vault.client.ClientHttpRequestFactoryFactory;
import org.springframework.vault.client.RestTemplateBuilder;
import org.springframework.vault.client.SimpleVaultEndpointProvider;
import org.springframework.vault.client.VaultClients;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.client.VaultEndpointProvider;
import org.springframework.vault.core.VaultTemplate;
@@ -48,7 +48,7 @@ import org.springframework.web.client.RestOperations;
* @author Spencer Gibb
* @author Mark Paluch
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public abstract class AbstractVaultConfiguration implements ApplicationContextAware {
private @Nullable ApplicationContext applicationContext;
@@ -105,8 +105,8 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
public VaultTemplate vaultTemplate() {
return new VaultTemplate(
restTemplateBuilder(vaultEndpointProvider(),
clientHttpRequestFactoryWrapper().getClientHttpRequestFactory()),
sessionManager());
getClientFactoryWrapper().getClientHttpRequestFactory()),
getBeanFactory().getBean("sessionManager", SessionManager.class));
}
/**
@@ -129,7 +129,7 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
Assert.notNull(clientAuthentication, "ClientAuthentication must not be null");
return new LifecycleAwareSessionManager(clientAuthentication,
threadPoolTaskScheduler(), restOperations());
getVaultThreadPoolTaskScheduler(), restOperations());
}
/**
@@ -145,7 +145,8 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
public SecretLeaseContainer secretLeaseContainer() throws Exception {
SecretLeaseContainer secretLeaseContainer = new SecretLeaseContainer(
vaultTemplate(), threadPoolTaskScheduler());
getBeanFactory().getBean("vaultTemplate", VaultTemplate.class),
getVaultThreadPoolTaskScheduler());
secretLeaseContainer.afterPropertiesSet();
secretLeaseContainer.start();
@@ -178,15 +179,16 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
/**
* Construct a {@link RestOperations} object configured for Vault session management
* and authentication usage.
* and authentication usage. Can be customized by overriding
* {@link #restTemplateBuilder(VaultEndpointProvider, ClientHttpRequestFactory)}.
*
* @return the {@link RestOperations} to be used for Vault access.
* @see #vaultEndpointProvider()
* @see #clientHttpRequestFactoryWrapper()
*/
public RestOperations restOperations() {
return VaultClients.createRestTemplate(vaultEndpointProvider(),
clientHttpRequestFactoryWrapper().getClientHttpRequestFactory());
return restTemplateBuilder(vaultEndpointProvider(),
getClientFactoryWrapper().getClientHttpRequestFactory()).build();
}
/**
@@ -247,6 +249,24 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
this.applicationContext = applicationContext;
}
BeanFactory getBeanFactory() {
Assert.state(applicationContext != null,
"ApplicationContext must be set before accessing getBeanFactory()");
return applicationContext;
}
ThreadPoolTaskScheduler getVaultThreadPoolTaskScheduler() {
return getBeanFactory().getBean("vaultThreadPoolTaskScheduler",
ThreadPoolTaskScheduler.class);
}
private ClientFactoryWrapper getClientFactoryWrapper() {
return getBeanFactory().getBean("clientHttpRequestFactoryWrapper",
ClientFactoryWrapper.class);
}
/**
* Wrapper for {@link ClientHttpRequestFactory} to not expose the bean globally.
*/

View File

@@ -22,8 +22,8 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.vault.authentication.AzureMsiAuthentication;
@@ -44,15 +44,14 @@ import static org.assertj.core.api.Assertions.assertThat;
class EnvironmentVaultConfigurationAzureMSIAuthenticationUnitTests {
@Configuration
@Import(EnvironmentVaultConfiguration.class)
static class MyConfig {
}
@Test
void shouldConfigureAuthentication(@Autowired ApplicationContext context) {
EnvironmentVaultConfiguration configuration = new EnvironmentVaultConfiguration();
configuration.setApplicationContext(context);
void shouldConfigureAuthentication(
@Autowired EnvironmentVaultConfiguration configuration) {
ClientAuthentication clientAuthentication = configuration.clientAuthentication();