Implemented (& tested) Spring-Boot-Autoconfiguration for SimpleMapperServcie
authorKai Moritz <kai@juplo.de>
Thu, 23 Jun 2016 08:14:44 +0000 (10:14 +0200)
committerKai Moritz <kai@juplo.de>
Thu, 23 Jun 2016 08:41:22 +0000 (10:41 +0200)
pom.xml
src/main/java/de/juplo/autoconfigure/SimpleMapperServiceAutoConfiguration.java [new file with mode: 0644]
src/main/java/de/juplo/jackson/SimpleMapperService.java
src/main/resources/META-INF/spring.factories [new file with mode: 0644]
src/test/java/de/juplo/autoconfigure/SimpleMapperServiceAutoConfigurationTest.java [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index f3fbdf4..feb0b1e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
       <optional>true</optional>
     </dependency>
 
+    <!-- Needed for the Spring-Boot autoconfiguration -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-autoconfigure</artifactId>
+      <optional>true</optional>
+    </dependency>
+
 
     <!-- Testing -->
     <dependency>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-configuration-processor</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
diff --git a/src/main/java/de/juplo/autoconfigure/SimpleMapperServiceAutoConfiguration.java b/src/main/java/de/juplo/autoconfigure/SimpleMapperServiceAutoConfiguration.java
new file mode 100644 (file)
index 0000000..1c9a471
--- /dev/null
@@ -0,0 +1,38 @@
+package de.juplo.autoconfigure;
+
+
+import com.fasterxml.jackson.core.JsonFactory;
+import de.juplo.jackson.SimpleMapperService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+
+
+
+/**
+ *
+ * @author Kai Moritz
+ */
+@ConditionalOnMissingBean(SimpleMapperService.class)
+public class SimpleMapperServiceAutoConfiguration
+{
+  private final Logger LOG =
+      LoggerFactory.getLogger(SimpleMapperServiceAutoConfiguration.class);
+
+
+  @Bean
+  public SimpleMapperService simpleMapperService(JsonFactory factory)
+  {
+    LOG.info("No SimpleMapperService configured: creating instance.");
+    return new SimpleMapperService(factory);
+  }
+
+  @Bean
+  @ConditionalOnMissingBean(JsonFactory.class)
+  public JsonFactory jsonFactory()
+  {
+    LOG.info("No JsonFactory configured: configuring default factory.");
+    return new JsonFactory();
+  }
+}
index a08d2f0..910b5bb 100644 (file)
@@ -12,8 +12,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.Spliterator;
 import java.util.stream.Stream;
+import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
 
 
 
@@ -22,18 +24,36 @@ import org.springframework.stereotype.Component;
  * @author kai
  */
 @Component
-public class SimpleMapperService extends SimpleMapper
+public class SimpleMapperService
+    extends
+      SimpleMapper
+    implements
+      InitializingBean
 {
-  @Autowired
+  @Autowired(required = false)
   private JsonFactory factory;
 
 
+  public SimpleMapperService() {}
+
   public SimpleMapperService(JsonFactory factory)
   {
     this.factory = factory;
   }
 
 
+  @Override
+  public void afterPropertiesSet() throws Exception
+  {
+    Assert.notNull(factory, "The attribute factory must be set!");
+  }
+
+  public JsonFactory getFactory()
+  {
+    return factory;
+  }
+
+
   public Spliterator<Object> getArraySpliterator(File file)
       throws
         IOException
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
new file mode 100644 (file)
index 0000000..0d7c0e1
--- /dev/null
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=de.juplo.autoconfigure.SimpleMapperServiceAutoConfiguration
diff --git a/src/test/java/de/juplo/autoconfigure/SimpleMapperServiceAutoConfigurationTest.java b/src/test/java/de/juplo/autoconfigure/SimpleMapperServiceAutoConfigurationTest.java
new file mode 100644 (file)
index 0000000..3f9f5f0
--- /dev/null
@@ -0,0 +1,132 @@
+package de.juplo.autoconfigure;
+
+
+import com.fasterxml.jackson.core.JsonFactory;
+import de.juplo.jackson.SimpleMapperService;
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+import org.springframework.context.annotation.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.annotation.Bean;
+
+
+
+public class SimpleMapperServiceAutoConfigurationTest
+{
+  private final Logger LOG =
+      LoggerFactory.getLogger(SimpleMapperServiceAutoConfigurationTest.class);
+
+
+  @Test
+  public void emptyConfiguration()
+  {
+    LOG.info("<-- Start Of New Test-Case!");
+
+    ConfigurableApplicationContext context = load(EmptyConfiguration.class);
+
+    SimpleMapperService service = context.getBean(SimpleMapperService.class);
+    assertNotNull(service);
+    assertNotNull(service.getFactory());
+    JsonFactory factory = context.getBean(JsonFactory.class);
+    assertNotNull(factory);
+    assertEquals(factory, service.getFactory());
+
+    context.close();
+  }
+
+  @Test
+  public void factoryConfigured()
+  {
+    LOG.info("<-- Start Of New Test-Case!");
+
+    ConfigurableApplicationContext context = load(FactoryConfigured.class);
+
+    SimpleMapperService service = context.getBean(SimpleMapperService.class);
+    assertNotNull(service);
+    assertNotNull(service.getFactory());
+    JsonFactory factory = context.getBean(JsonFactory.class);
+    assertNotNull(factory);
+    assertEquals(FactoryConfigured.factory, factory);
+    assertEquals(factory, service.getFactory());
+
+    context.close();
+  }
+
+  @Test
+  public void serviceConfigured()
+  {
+    LOG.info("<-- Start Of New Test-Case!");
+
+    ConfigurableApplicationContext context = load(ServiceConfigured.class);
+
+    SimpleMapperService service = context.getBean(SimpleMapperService.class);
+    assertNotNull(service);
+    assertNotNull(service.getFactory());
+    assertEquals(ServiceConfigured.factory, service.getFactory());
+    try
+    {
+      context.getBean(JsonFactory.class);
+      fail("A bean of type JsonFactory was found!");
+    }
+    catch(NoSuchBeanDefinitionException e)
+    {
+      LOG.trace("expected exception", e);
+    }
+
+    context.close();
+  }
+
+
+  @Configuration
+  static class EmptyConfiguration
+  {
+  }
+
+  @Configuration
+  static class FactoryConfigured
+  {
+    static JsonFactory factory = new JsonFactory();
+
+
+    @Bean
+    public JsonFactory factory()
+    {
+      return factory;
+    }
+  }
+
+  @Configuration
+  static class ServiceConfigured
+  {
+    static JsonFactory factory = new JsonFactory();
+    static SimpleMapperService service = new SimpleMapperService(factory);
+
+
+    @Bean
+    public SimpleMapperService service()
+    {
+      return service;
+    }
+  }
+
+
+  private ConfigurableApplicationContext load(Class<?> config, String... pairs)
+  {
+    AnnotationConfigApplicationContext ctx =
+        new AnnotationConfigApplicationContext();
+    ctx.register(config);
+    ctx.register(SimpleMapperServiceAutoConfiguration.class); // << Does not work as expected, if the autoconfiguration is registered before the configuration!
+    AutoConfigurationReportLoggingInitializer report =
+        new AutoConfigurationReportLoggingInitializer();
+    report.initialize(ctx);
+    ctx.refresh();
+    return ctx;
+  }
+}