INT-2888 Fix MapToObjectTransformerParser CL Issue
In the parent-child environment configuration that relies on class names may produce a `ClassNotFoundException`. * remove usage of `ClassLoader` in the `MapToObjectTransformerParser` and allow to use the `ConversionService` from application context * remove deprecation from `MapToObjectTransformer` * refactor `MapToObjectTransformer` to use `IntegrationObjectSupport#getConversionService()` * remove fallback to the `beanFactory#getConversionService()` in the `ExpressionUtils` JIRA: https://jira.springsource.org/browse/INT-2888 INT-2928: Do Not Fallback to BF's ConversionService * Polishing according PR's comments * Important note about `conversionService` & `integrationConversionService` beans * Link a JIRA about elimination of `BeanFactory`'s `ConversionService` usage * Add a note to the 2.2-3.0 Migration Guide JIRA: https://jira.springsource.org/browse/INT-2928 INT-2888 Doc Polishing
This commit is contained in:
committed by
Gary Russell
parent
e994c4dab3
commit
77fae8844a
@@ -9,27 +9,27 @@
|
||||
<int:channel id="output">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<int:map-to-object-transformer input-channel="input"
|
||||
output-channel="output"
|
||||
|
||||
<int:map-to-object-transformer input-channel="input"
|
||||
output-channel="output"
|
||||
type="org.springframework.integration.config.xml.MapToObjectTransformerParserTests$Person"/>
|
||||
|
||||
|
||||
<int:channel id="inputA"/>
|
||||
<int:channel id="outputA">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<int:map-to-object-transformer input-channel="inputA"
|
||||
output-channel="outputA"
|
||||
|
||||
<int:map-to-object-transformer input-channel="inputA"
|
||||
output-channel="outputA"
|
||||
ref="person"/>
|
||||
|
||||
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
|
||||
|
||||
<bean id="conversionService" name="integrationConversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
|
||||
<property name="converters">
|
||||
<list>
|
||||
<bean class="org.springframework.integration.config.xml.MapToObjectTransformerParserTests$StringToAddressConverter" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="person" class="org.springframework.integration.config.xml.MapToObjectTransformerParserTests$Person" scope="prototype"/>
|
||||
</beans>
|
||||
|
||||
@@ -20,43 +20,49 @@ import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gunnar Hillert
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class MapToObjectTransformerTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void testMapToObjectTransformation(){
|
||||
Map map = new HashMap();
|
||||
public void testMapToObjectTransformation() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("fname", "Justin");
|
||||
map.put("lname", "Case");
|
||||
Address address = new Address();
|
||||
address.setStreet("1123 Main st");
|
||||
map.put("address", address);
|
||||
|
||||
Message message = MessageBuilder.withPayload(map).build();
|
||||
Message<?> message = MessageBuilder.withPayload(map).build();
|
||||
|
||||
MapToObjectTransformer transformer = new MapToObjectTransformer(Person.class);
|
||||
transformer.setBeanFactory(this.getBeanFactory());
|
||||
Message newMessage = transformer.transform(message);
|
||||
Message<?> newMessage = transformer.transform(message);
|
||||
Person person = (Person) newMessage.getPayload();
|
||||
assertNotNull(person);
|
||||
assertEquals("Justin", person.getFname());
|
||||
@@ -67,20 +73,20 @@ public class MapToObjectTransformerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapToObjectTransformationWithPrototype(){
|
||||
Map map = new HashMap();
|
||||
public void testMapToObjectTransformationWithPrototype() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("fname", "Justin");
|
||||
map.put("lname", "Case");
|
||||
Address address = new Address();
|
||||
address.setStreet("1123 Main st");
|
||||
map.put("address", address);
|
||||
|
||||
Message message = MessageBuilder.withPayload(map).build();
|
||||
Message<?> message = MessageBuilder.withPayload(map).build();
|
||||
StaticApplicationContext ac = new StaticApplicationContext();
|
||||
ac.registerPrototype("person", Person.class);
|
||||
MapToObjectTransformer transformer = new MapToObjectTransformer("person");
|
||||
transformer.setBeanFactory(ac.getBeanFactory());
|
||||
Message newMessage = transformer.transform(message);
|
||||
Message<?> newMessage = transformer.transform(message);
|
||||
Person person = (Person) newMessage.getPayload();
|
||||
assertNotNull(person);
|
||||
assertEquals("Justin", person.getFname());
|
||||
@@ -91,20 +97,22 @@ public class MapToObjectTransformerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapToObjectTransformationWithConversionService(){
|
||||
Map map = new HashMap();
|
||||
public void testMapToObjectTransformationWithConversionService() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("fname", "Justin");
|
||||
map.put("lname", "Case");
|
||||
map.put("address", "1123 Main st");
|
||||
|
||||
Message message = MessageBuilder.withPayload(map).build();
|
||||
Message<?> message = MessageBuilder.withPayload(map).build();
|
||||
|
||||
MapToObjectTransformer transformer = new MapToObjectTransformer(Person.class);
|
||||
ConfigurableBeanFactory beanFactory = this.getBeanFactory();
|
||||
((GenericConversionService)beanFactory.getConversionService()).addConverter(new StringToAddressConverter());
|
||||
BeanFactory beanFactory = this.getBeanFactory();
|
||||
ConverterRegistry conversionService =
|
||||
beanFactory.getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, ConverterRegistry.class);
|
||||
conversionService.addConverter(new StringToAddressConverter());
|
||||
transformer.setBeanFactory(beanFactory);
|
||||
|
||||
Message newMessage = transformer.transform(message);
|
||||
Message<?> newMessage = transformer.transform(message);
|
||||
Person person = (Person) newMessage.getPayload();
|
||||
assertNotNull(person);
|
||||
assertEquals("Justin", person.getFname());
|
||||
@@ -113,45 +121,73 @@ public class MapToObjectTransformerTests {
|
||||
assertEquals("1123 Main st", person.getAddress().getStreet());
|
||||
}
|
||||
|
||||
private ConfigurableBeanFactory getBeanFactory(){
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
GenericConversionService conversionService = new DefaultConversionService();
|
||||
beanFactory.setConversionService(conversionService);
|
||||
return beanFactory;
|
||||
private BeanFactory getBeanFactory() {
|
||||
GenericApplicationContext ctx = TestUtils.createTestApplicationContext();
|
||||
Constructor<?> constructorToUse = null;
|
||||
try {
|
||||
// Add the integrationConversionService (reflection needed because of package protection)
|
||||
final Class<?> conversionServiceCreatorClass = ClassUtils.forName("org.springframework.integration.context.ConversionServiceCreator",
|
||||
ClassUtils.getDefaultClassLoader());
|
||||
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
|
||||
public Constructor<?> run() throws Exception {
|
||||
return conversionServiceCreatorClass.getDeclaredConstructor((Class[]) null);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("Unexpected Privilege Exception: ", e);
|
||||
}
|
||||
|
||||
ctx.addBeanFactoryPostProcessor((BeanFactoryPostProcessor) BeanUtils.instantiateClass(constructorToUse));
|
||||
ctx.refresh();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public static class Person{
|
||||
public static class Person {
|
||||
|
||||
private String fname;
|
||||
|
||||
private String lname;
|
||||
|
||||
private String ssn;
|
||||
|
||||
private Address address;
|
||||
|
||||
public String getSsn() {
|
||||
return ssn;
|
||||
}
|
||||
|
||||
public void setSsn(String ssn) {
|
||||
this.ssn = ssn;
|
||||
}
|
||||
|
||||
public String getFname() {
|
||||
return fname;
|
||||
}
|
||||
|
||||
public void setFname(String fname) {
|
||||
this.fname = fname;
|
||||
}
|
||||
|
||||
public String getLname() {
|
||||
return lname;
|
||||
}
|
||||
|
||||
public void setLname(String lname) {
|
||||
this.lname = lname;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Address {
|
||||
|
||||
private String street;
|
||||
|
||||
public String getStreet() {
|
||||
@@ -163,7 +199,8 @@ public class MapToObjectTransformerTests {
|
||||
}
|
||||
}
|
||||
|
||||
public class StringToAddressConverter implements Converter<String, Address>{
|
||||
public class StringToAddressConverter implements Converter<String, Address> {
|
||||
|
||||
public Address convert(String source) {
|
||||
Address address = new Address();
|
||||
address.setStreet(source);
|
||||
|
||||
Reference in New Issue
Block a user