开发者

Is there a better way to Configure Bean?

开发者 https://www.devze.com 2023-03-19 12:42 出处:网络
Can the following Spring DI xml be improved? Below the xml is the programmatic approach of configuring the target bean.

Can the following Spring DI xml be improved? Below the xml is the programmatic approach of configuring the target bean.

<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
    factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" />
<bean
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="jacksonSerializationConfig" />
    <property name="targetMethod" value="setSerializationInclusion" />
    <property name="arguments">
        <list>
            <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_N开发者_开发百科ULL</value>
        </list>
    </property>
</bean>

ObjectMapper mapper = new ObjectMapper(); mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);


XML is a really bad way of doing this. Yes, you can do this, but it's much easier to write a FactoryBean which configures your ObjectMapper:

public class MyObjectMapperFactoryBean extends AbstractFactoryBean<ObjectMapper> {
   public Class<ObjectMapper> getObjectType() {
      return ObjectMapper.class;
   }

   public ObjectMapper createInstance() {
      // create and return ObjectMapper 
   }
}

and then in your XML:

<bean id="jacksonObjectMapper" class="x.y.MyObjectMapperFactoryBean" />


Still not totally ideal, but a little cleaner:

<bean id="objectMapperBuilder1" class="org.codehaus.jackson.map.ObjectMapper"/>
<bean id="objectMapperBuilder2" factory-bean="objectMapperBuilder1" factory-method="setSerializationInclusion">
    <constructor-arg value="NON_NULL"/>
</bean>
<bean id="jsonWriter" factory-bean="objectMapperBuilder2" factory-method="writerWithDefaultPrettyPrinter" />
<!-- etc, etc -->

One downside is that you'll have unnecessary bean instances in memory. (I'm using this method, and I'll live with it until Spring decides to handle these). There are many threads here and on the Spring forums asking for support with fluent setters like the builder pattern used by Jackson, but until then you have to choose the lesser evil for you.


I agree with @skaffman's general approach of using a FactoryBean in place of the unavoidably convoluted Spring XML bean configuration to configure a Jackson ObjectMapper. Spring 3.2+ now provides such a FactoryBean out of the box. See JacksonObjectMapperFactoryBean / Jackson2ObjectMapperFactoryBean. Here's an example of the Spring XML to configure the ObjectMapper via the Spring FactoryBean -

<bean id="jacksonObjectMapper" factory-bean="&amp;jacksonObjectMapperFactoryBean" factory-method="getObject"/>  
<bean id="jacksonObjectMapperFactoryBean" class="org.springframework.http.converter.json.JacksonObjectMapperFactoryBean"> 
  <property name="featuresToDisable">
    <array>
      <util:constant static-field="org.codehaus.jackson.map.SerializationConfig$Feature.WRITE_NULL_PROPERTIES"/>
    </array>
  </property>
</bean> 

(Note the need to use &amp in the 'factory-bean' attribute to instruct Spring to use the factory method on the FactoryBean itself, rather than the bean it creates).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号