INT-1178 separated conversionService creation from its initialization with converters

This commit is contained in:
Oleg Zhurakousky
2010-07-20 15:38:02 +00:00
parent 970bde86dc
commit a94a5db38f
5 changed files with 73 additions and 65 deletions

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.integration.config.xml;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -24,8 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.integration.util.ConverterRegistrar;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -36,14 +33,14 @@ import org.w3c.dom.Element;
*/
public class ConverterParser extends AbstractBeanDefinitionParser {
private final ManagedSet<Object> converters = new ManagedSet<Object>();
private String CONVERTER_REGISTRAR = "converterRegistrar";
private boolean notInitialized = true;
/* (non-Javadoc)
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
*/
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(CONVERTER_REGISTRAR)){
this.defineConverterRegistrar(parserContext);
if (notInitialized){
this.initializeConversionServiceInfrustructure(parserContext);
}
BeanComponentDefinition converterDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
if (converterDefinition == null){
@@ -58,10 +55,14 @@ public class ConverterParser extends AbstractBeanDefinitionParser {
/*
*
*/
private void defineConverterRegistrar(ParserContext parserContext){
BeanDefinitionBuilder conversionServiceBuilder = BeanDefinitionBuilder.rootBeanDefinition(ConverterRegistrar.class);
private void initializeConversionServiceInfrustructure(ParserContext parserContext){
String contextPackage = "org.springframework.integration.context.";
BeanDefinitionBuilder creatorBuilder = BeanDefinitionBuilder.rootBeanDefinition(contextPackage + "ConversionServiceCreator");
BeanDefinitionReaderUtils.registerWithGeneratedName(creatorBuilder.getBeanDefinition(), parserContext.getRegistry());
BeanDefinitionBuilder conversionServiceBuilder = BeanDefinitionBuilder.rootBeanDefinition(contextPackage + "ConverterRegistrar");
conversionServiceBuilder.addConstructorArgValue(converters);
BeanDefinitionHolder bdHolder = new BeanDefinitionHolder(conversionServiceBuilder.getBeanDefinition(), CONVERTER_REGISTRAR);
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, parserContext.getRegistry());
BeanDefinitionReaderUtils.registerWithGeneratedName(conversionServiceBuilder.getBeanDefinition(), parserContext.getRegistry());
notInitialized = false;
}
}

View File

@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.util;
import java.util.Set;
package org.springframework.integration.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -25,34 +23,17 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
/**
* @author Oleg Zhurakousky
* @since 2.0
* @sini 2.0
*/
public class ConverterRegistrar implements BeanFactoryPostProcessor {
private final Set<Converter<?, ?>> converters;
public ConverterRegistrar(Set<Converter<?, ?>> converters){
this.converters = converters;
}
/**
* This method will add converters to the SI's conversion service - {@link SI#CONVERSION_SERVICE}
* If SI's conversion service does not exist, then an instance of the {@link ConversionService} will
* be created and registered under the name {@link SI#CONVERSION_SERVICE}
*/
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (!beanFactory.containsBean(SI.CONVERSION_SERVICE)){
class ConversionServiceCreator implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (!beanFactory.containsBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME)){
BeanDefinitionBuilder conversionServiceBuilder = BeanDefinitionBuilder.rootBeanDefinition(ConversionServiceFactoryBean.class);
BeanDefinitionHolder csHolder = new BeanDefinitionHolder(conversionServiceBuilder.getBeanDefinition(), SI.CONVERSION_SERVICE);
BeanDefinitionHolder csHolder = new BeanDefinitionHolder(conversionServiceBuilder.getBeanDefinition(), IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(csHolder, (BeanDefinitionRegistry) beanFactory);
}
GenericConversionService conversionService = beanFactory.getBean(SI.CONVERSION_SERVICE, GenericConversionService.class);
ConversionServiceFactory.registerConverters(converters, conversionService);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2002-2010 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
*
* http://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.integration.context;
import java.util.Set;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.util.Assert;
/**
* @author Oleg Zhurakousky
* @since 2.0
*/
class ConverterRegistrar implements InitializingBean, BeanFactoryAware {
private final Set<Converter<?, ?>> converters;
private BeanFactory beanFactory;
public ConverterRegistrar(Set<Converter<?, ?>> converters){
this.converters = converters;
}
public void afterPropertiesSet() throws Exception {
GenericConversionService conversionService = beanFactory.getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, GenericConversionService.class);
Assert.notNull(conversionService, "can not locate '" + IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME + "' ");
ConversionServiceFactory.registerConverters(converters, conversionService);
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

View File

@@ -1,25 +0,0 @@
/*
* Copyright 2002-2010 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
*
* http://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.integration.util;
/**
* @author Oleg Zhurakousky
* @since 2.0
*/
public interface SI {
public String CONVERSION_SERVICE = "integrationConversionService";
}

View File

@@ -25,7 +25,7 @@ import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.integration.util.SI;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
@@ -42,12 +42,12 @@ public class ConverterParserWithExistingConversionServiceTests {
private ApplicationContext applicationContext;
@Autowired
@Qualifier(SI.CONVERSION_SERVICE)
@Qualifier(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME)
private ConversionService conversionService;
@Test
public void testConversionServiceAvailability(){
Assert.isTrue(applicationContext.getBean(SI.CONVERSION_SERVICE).equals(conversionService));
Assert.isTrue(applicationContext.getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME).equals(conversionService));
Assert.isTrue(conversionService.canConvert(TestBean1.class, TestBean2.class));
Assert.isTrue(conversionService.canConvert(TestBean1.class, TestBean3.class));
}
@@ -58,8 +58,8 @@ public class ConverterParserWithExistingConversionServiceTests {
GenericApplicationContext childContext = new GenericApplicationContext();
childContext.setParent(parentContext);
GenericConversionService conversionServiceParent = parentContext.getBean(SI.CONVERSION_SERVICE,GenericConversionService.class);
GenericConversionService conversionServiceChild = childContext.getBean(SI.CONVERSION_SERVICE,GenericConversionService.class);
GenericConversionService conversionServiceParent = parentContext.getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME,GenericConversionService.class);
GenericConversionService conversionServiceChild = childContext.getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME,GenericConversionService.class);
Assert.isTrue(conversionServiceParent == conversionServiceChild); // validating that they are pointing to the same object
conversionServiceChild.addConverter(new TestConverter());
conversionServiceChild.addConverter(new TestConverter3());