Use Published Conversion Service

This configuration class publishes an ObjectDirectoryMapper
instance that is configured with the published ConversionService,
including any custom converters it is configured with.

Closes gh-633
This commit is contained in:
Josh Cummings
2025-02-12 17:09:21 -07:00
parent a09489f2b7
commit 239242c78c
4 changed files with 145 additions and 0 deletions

View File

@@ -16,6 +16,7 @@ dependencies {
management platform(project(":spring-ldap-dependencies"))
api "org.springframework:spring-core"
api "org.springframework:spring-beans"
api "org.springframework:spring-context"
api "org.springframework:spring-tx"
api "io.micrometer:micrometer-core"

View File

@@ -0,0 +1,63 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.convert;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
/**
* A {@link BeanFactoryPostProcessor} to add Spring LDAP converters to the default
* {@link ConversionService}.
*
* <p>
* Note that this post processor will ignore user-defined {@link ConversionService} beans
* named {@code conversionService}.
*
* <p>
* In that case, you can apply {@link ConverterUtils#addDefaultConverters} to your
* instance instead
*
* @author Josh Cummings
* @since 3.3
*/
public final class ConversionServiceBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private static final String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
/**
* {@inheritDoc}
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (hasUserDefinedConversionService(beanFactory)) {
return;
}
ConversionService service = beanFactory.getConversionService();
if (service instanceof ConverterRegistry registry) {
ConverterUtils.addDefaultConverters(registry);
}
}
private boolean hasUserDefinedConversionService(ConfigurableListableBeanFactory beanFactory) {
return beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)
&& beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class);
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.odm.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Fallback;
import org.springframework.core.convert.ConversionService;
import org.springframework.ldap.convert.ConversionServiceBeanFactoryPostProcessor;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper;
/**
* Configuration class for {@link ObjectDirectoryMapper}
*
* @author Josh Cummings
* @since 3.3
*/
@Configuration(proxyBeanMethods = false)
public class ObjectDirectoryMapperConfiguration {
@Bean
ConversionServiceBeanFactoryPostProcessor conversionServiceBeanPostProcessor() {
return new ConversionServiceBeanFactoryPostProcessor();
}
@Bean
@Fallback
ObjectDirectoryMapper objectDirectoryMapper(ConversionService conversionService) {
DefaultObjectDirectoryMapper objectDirectoryMapper = new DefaultObjectDirectoryMapper();
objectDirectoryMapper.setConversionService(conversionService);
return objectDirectoryMapper;
}
}

View File

@@ -14,6 +14,38 @@ The Spring LDAP project offers a similar ability with respect to LDAP directorie
* `void update(Object entry)`
* `void delete(Object entry)`
[[configuration]]
== Configuration
`LdapTemplate` constructs a default `ObjectDirectoryMapper` which typically renders additional configuration unnecessary.
However, you can also make `ObjectDirectoryMapper` available as a `@Bean` by importing `ObjectDirectoryMapperConfiguration` like so:
[source,java]
----
@Import(ObjectDirectoryMapperConfiguration.class)
@Configuration
public class LdapConfig {
// ...
}
----
You can then supply it to your `LdapTemplate` instance as follows:
[source,java]
----
@Bean
LdapTemplate ldapTemplate(ContextSource contextSource, ObjectDirectoryMapper odm) {
LdapTemplate ldap = new LdapTemplate(contextSource);
ldap.setObjectDirectoryMapper(odm);
return ldap;
}
----
Using this import provides the benefit that it will automatically configure `ObjectDirectoryMapper` with the `ConversionService` in the `ApplicationContext`.
This means that Spring LDAP will use your configured `Converter` instances.
[[annotations]]
== Annotations