diff --git a/README.md b/README.md
index 25e89a1..6b778e7 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,12 @@ dropwizard-spring
With **dropwizard-spring** you configure your dropwizard components (resources, healthchecks, jersey providers, managed objects, servlets, filters, etc.)
entirely with spring, and tell the spring service which components to enable using a simple YAML configuration.
-With **dropwizard-spring** it is not necessary to subclass `com.yammer.dropwizard.Service`, instead you reference the provided
-`com.hmsonline.dropwizard.spring.SpringService` class as your service class.
+With **dropwizard-spring** it is not necessary to subclass `io.dropwizard.Application`, instead you reference the provided
+`com.hmsonline.dropwizard.spring.SpringService` class as your application class.
+With **dropwizard-spring** you can use XML or annotation based (Java Based Config) spring bean definitions
+
+To see **dropwizard-spring** in action look into the example folder of this project
## Maven Configuration
@@ -107,6 +110,11 @@ This is required to have maven build a "fat," executable jar file.
# The location of one or more beans.xml files
configLocations:
- conf/dropwizard-beans.xml
+
+ # Package to look for JavaConfig classes annotated with @Configuration
+ # Set either javaConfigBasePackages or configLocations
+ javaConfigBasePackages:
+ - com.yourpackage.spring.config
# Servlet Filter
# List of FilterConfiguration
diff --git a/example/java-config/config.yaml b/example/java-config/config.yaml
new file mode 100644
index 0000000..12177c3
--- /dev/null
+++ b/example/java-config/config.yaml
@@ -0,0 +1,8 @@
+spring:
+ appContextType: app
+
+ javaConfigBasePackages:
+ - com.hmsonline.dropwizard.spring.config
+
+ resources:
+ - helloResource
\ No newline at end of file
diff --git a/example/java-config/pom.xml b/example/java-config/pom.xml
new file mode 100644
index 0000000..5dae578
--- /dev/null
+++ b/example/java-config/pom.xml
@@ -0,0 +1,160 @@
+
+
+
+ 4.0.0
+
+ 3.0.0
+
+
+ com.hmsonline
+ dropwizard-spring-javaconfig-example
+ 0.6.2-SNAPSHOT
+ jar
+
+ Dropwizard-Spring Java Config Example
+
+
+ UTF-8
+ UTF-8
+ com.hmsonline.dropwizard.spring.SpringService
+
+
+
+
+ com.hmsonline
+ dropwizard-spring
+ ${project.version}
+
+
+ junit
+ junit
+ 4.10
+ test
+
+
+
+
+
+
+ maven-shade-plugin
+ 1.7
+
+ true
+
+
+ ${mainClass}
+
+
+
+ META-INF/spring.handlers
+
+
+ META-INF/spring.schemas
+
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+ maven-jar-plugin
+ 2.4
+
+
+
+ true
+ ${mainClass}
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.6
+ 1.6
+
+
+
+ maven-source-plugin
+ 2.1.2
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ maven-javadoc-plugin
+ 2.8.1
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ maven-deploy-plugin
+ 2.7
+
+
+ org.apache.maven.wagon
+ wagon-ssh
+ 2.2
+
+
+
+
+ maven-site-plugin
+ 3.0
+
+
+
+ maven-project-info-reports-plugin
+ 2.4
+
+ false
+ false
+
+
+
+ maven-javadoc-plugin
+ 2.8.1
+
+
+
+
+
+
+
+
+
diff --git a/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/GreetingService.java b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/GreetingService.java
new file mode 100644
index 0000000..0b115fd
--- /dev/null
+++ b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/GreetingService.java
@@ -0,0 +1,12 @@
+package com.hmsonline.dropwizard.spring;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class GreetingService {
+
+ public String greet(String name) {
+ return "Hi " + name;
+ }
+
+}
diff --git a/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java
new file mode 100644
index 0000000..44d3243
--- /dev/null
+++ b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 Health Market Science, Inc.
+
+package com.hmsonline.dropwizard.spring;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Component
+@Path("/hello")
+public class HelloResource {
+
+ @Autowired
+ private MessageBean messageBean;
+
+ @Autowired
+ private GreetingService greetingService;
+
+ @GET
+ @Path("/world")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Object hello(){
+ return greetingService.greet(messageBean.getMessage());
+ }
+
+}
diff --git a/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/MessageBean.java b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/MessageBean.java
new file mode 100644
index 0000000..75726cc
--- /dev/null
+++ b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/MessageBean.java
@@ -0,0 +1,17 @@
+package com.hmsonline.dropwizard.spring;
+
+import org.springframework.stereotype.Component;
+
+public class MessageBean {
+
+ private String message;
+
+ public MessageBean(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/config/Config.java b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/config/Config.java
new file mode 100644
index 0000000..52d03d4
--- /dev/null
+++ b/example/java-config/src/main/java/com/hmsonline/dropwizard/spring/config/Config.java
@@ -0,0 +1,17 @@
+package com.hmsonline.dropwizard.spring.config;
+
+import com.hmsonline.dropwizard.spring.MessageBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan("com.hmsonline.dropwizard.spring")
+public class Config {
+
+ @Bean
+ MessageBean createMessageBean() {
+ return new MessageBean("Java Config");
+ }
+
+}
diff --git a/example/java-config/src/main/resources/banner.txt b/example/java-config/src/main/resources/banner.txt
new file mode 100644
index 0000000..1b6bb83
--- /dev/null
+++ b/example/java-config/src/main/resources/banner.txt
@@ -0,0 +1,6 @@
+================================================================================
+
+ dropwizard-javaconfig-spring-example
+
+================================================================================
+
diff --git a/example/config.yaml b/example/xml/config.yaml
similarity index 100%
rename from example/config.yaml
rename to example/xml/config.yaml
diff --git a/example/pom.xml b/example/xml/pom.xml
similarity index 99%
rename from example/pom.xml
rename to example/xml/pom.xml
index a0c84e7..96816eb 100644
--- a/example/pom.xml
+++ b/example/xml/pom.xml
@@ -9,7 +9,7 @@
com.hmsonline
dropwizard-spring-example
- 0.2.1-SNAPSHOT
+ 0.6.2-SNAPSHOT
jar
Dropwizard-Spring Example
diff --git a/example/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java b/example/xml/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java
similarity index 100%
rename from example/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java
rename to example/xml/src/main/java/com/hmsonline/dropwizard/spring/HelloResource.java
diff --git a/example/src/main/resources/banner.txt b/example/xml/src/main/resources/banner.txt
similarity index 100%
rename from example/src/main/resources/banner.txt
rename to example/xml/src/main/resources/banner.txt
diff --git a/example/src/main/resources/dropwizard-service.xml b/example/xml/src/main/resources/dropwizard-service.xml
similarity index 100%
rename from example/src/main/resources/dropwizard-service.xml
rename to example/xml/src/main/resources/dropwizard-service.xml
diff --git a/src/main/java/com/hmsonline/dropwizard/spring/ApplicationContextTypeDeserializer.java b/src/main/java/com/hmsonline/dropwizard/spring/ApplicationContextTypeDeserializer.java
new file mode 100644
index 0000000..40c3b7c
--- /dev/null
+++ b/src/main/java/com/hmsonline/dropwizard/spring/ApplicationContextTypeDeserializer.java
@@ -0,0 +1,34 @@
+package com.hmsonline.dropwizard.spring;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+public final class ApplicationContextTypeDeserializer extends JsonDeserializer {
+
+ @Override
+ public SpringConfiguration.ApplicationContextType deserialize(final JsonParser parser, final DeserializationContext context) throws IOException, JsonProcessingException {
+ final String jsonValue = parser.getText();
+
+ for (SpringConfiguration.ApplicationContextType applicationContextType : SpringConfiguration.ApplicationContextType.values()) {
+ if (applicationContextType.getName().equals(jsonValue)) {
+ return applicationContextType;
+ }
+ }
+
+ throw new JsonMappingException(
+ MessageFormat.format(
+ "Configuration Error: appContextType must be either \"{0}\" or \"{1}\"",
+ SpringConfiguration.ApplicationContextType.WEB_APPLICATION_CONTEXT.getName(),
+ SpringConfiguration.ApplicationContextType.APPLICATION_CONTEXT.getName()
+ )
+ );
+
+ }
+
+}
diff --git a/src/main/java/com/hmsonline/dropwizard/spring/SpringConfiguration.java b/src/main/java/com/hmsonline/dropwizard/spring/SpringConfiguration.java
index 2d9a542..d52ea31 100644
--- a/src/main/java/com/hmsonline/dropwizard/spring/SpringConfiguration.java
+++ b/src/main/java/com/hmsonline/dropwizard/spring/SpringConfiguration.java
@@ -2,35 +2,61 @@
package com.hmsonline.dropwizard.spring;
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.hmsonline.dropwizard.spring.web.FilterConfiguration;
import com.hmsonline.dropwizard.spring.web.ServletConfiguration;
import io.dropwizard.Configuration;
import org.hibernate.validator.constraints.NotEmpty;
+import java.io.IOException;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SpringConfiguration extends Configuration {
- public static final String WEB_APPLICATION_CONTEXT = "web";
- public static final String APPLICATION_CONTEXT = "app";
+ public enum ApplicationContextType {
+ WEB_APPLICATION_CONTEXT("web"),APPLICATION_CONTEXT("app");
+
+ private String name;
+
+ ApplicationContextType(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+
public static final String CLASSPATH_CONFIG = "classpath";
public static final String FILE_CONFIG = "file";
@NotEmpty
@JsonProperty
- private String appContextType;
+ @JsonDeserialize(using = ApplicationContextTypeDeserializer.class)
+ private ApplicationContextType appContextType;
@NotEmpty
@JsonProperty
private String configLocationsType;
- @NotEmpty
@JsonProperty
private List configLocations;
+ @JsonProperty
+ private List javaConfigBasePackages;
+
@NotEmpty
@JsonProperty
private List resources;
@@ -63,7 +89,7 @@ public class SpringConfiguration extends Configuration {
@JsonProperty
private Map servlets;
- public String getAppContextType() {
+ public ApplicationContextType getAppContextType() {
return appContextType;
}
@@ -126,4 +152,12 @@ public String getConfigLocationsType() {
public void setConfigLocationsType(String configLocationsType) {
this.configLocationsType = configLocationsType;
}
+
+ public List getJavaConfigBasePackages() {
+ return javaConfigBasePackages;
+ }
+
+ public void setJavaConfigBasePackages(List javaConfigBasePackages) {
+ this.javaConfigBasePackages = javaConfigBasePackages;
+ }
}
diff --git a/src/main/java/com/hmsonline/dropwizard/spring/SpringService.java b/src/main/java/com/hmsonline/dropwizard/spring/SpringService.java
index 42e4366..719399a 100644
--- a/src/main/java/com/hmsonline/dropwizard/spring/SpringService.java
+++ b/src/main/java/com/hmsonline/dropwizard/spring/SpringService.java
@@ -22,13 +22,17 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
+import static com.hmsonline.dropwizard.spring.SpringConfiguration.ApplicationContextType.WEB_APPLICATION_CONTEXT;
+
public class SpringService extends Application {
private static final Logger LOG = LoggerFactory.getLogger(SpringService.class);
@@ -242,33 +246,74 @@ private ApplicationContext initSpringParent() {
}
private ApplicationContext initSpring(SpringConfiguration config, ApplicationContext parent) {
+
+ if (config.getJavaConfigBasePackages() != null && config.getJavaConfigBasePackages().size() > 0) {
+ return initJavaConfigSpring(config, parent);
+ }
+
+ if (config.getConfigLocations() != null && config.getConfigLocations().size() > 0) {
+ return initXmlSpring(parent, config);
+
+ }
+
+ throw new IllegalArgumentException("Configuration Error: You must specify either configLocation or javaConfigBasePackages");
+
+ }
+
+ private ApplicationContext initXmlSpring(ApplicationContext parent, SpringConfiguration config) {
+
ApplicationContext appCtx = null;
- // Get Application Context Type
- String ctxType = config.getAppContextType();
// Get Config Location Type.
String cfgLocationType = config.getConfigLocationsType();
- String[] configLocations = config.getConfigLocations().toArray(new String[config.getConfigLocations().size()]);
- if (SpringConfiguration.WEB_APPLICATION_CONTEXT.equals(ctxType)) {
- // Create Web Application Context.
- appCtx = new XmlRestWebApplicationContext(configLocations, cfgLocationType, true, parent);
+ String[] configLocations = config.getConfigLocations().toArray(new String[config.getConfigLocations().size()]);
- } else if (SpringConfiguration.APPLICATION_CONTEXT.equals(ctxType)) {
+ switch (config.getAppContextType()) {
+
+ case WEB_APPLICATION_CONTEXT:
+ // Create Web Application Context.
+ appCtx = new XmlRestWebApplicationContext(configLocations, cfgLocationType, true, parent);
+ break;
+
+ case APPLICATION_CONTEXT:
+ // Create Application Context.
+ if (SpringConfiguration.FILE_CONFIG.equals(cfgLocationType)) {
+ appCtx = new FileSystemXmlApplicationContext(configLocations, true, parent);
+ } else if (SpringConfiguration.CLASSPATH_CONFIG.equals(cfgLocationType)) {
+ appCtx = new ClassPathXmlApplicationContext(configLocations, true, parent);
+ } else {
+ throw new IllegalArgumentException(MessageFormat.format("Configuration Error: configLocationsType must be either \"{0}\" or \"{1}\"", SpringConfiguration.FILE_CONFIG, SpringConfiguration.CLASSPATH_CONFIG));
+ }
- // Create Application Context.
- if (SpringConfiguration.FILE_CONFIG.equals(cfgLocationType)) {
- appCtx = new FileSystemXmlApplicationContext(configLocations, true, parent);
- } else if (SpringConfiguration.CLASSPATH_CONFIG.equals(cfgLocationType)) {
- appCtx = new ClassPathXmlApplicationContext(configLocations, true, parent);
- } else {
- throw new IllegalArgumentException(MessageFormat.format("Configuration Error: configLocationsType must be either \"{0}\" or \"{1}\"", SpringConfiguration.FILE_CONFIG, SpringConfiguration.CLASSPATH_CONFIG));
- }
- } else {
- throw new IllegalArgumentException(MessageFormat.format("Configuration Error: appContextType must be either \"{0}\" or \"{1}\"", SpringConfiguration.WEB_APPLICATION_CONTEXT, SpringConfiguration.APPLICATION_CONTEXT));
}
+
+
return appCtx;
}
+ private ApplicationContext initJavaConfigSpring(SpringConfiguration config, ApplicationContext parent) {
+ String[] javaConfigBasePackages = config.getJavaConfigBasePackages().toArray(new String[config.getJavaConfigBasePackages().size()]);
+
+ switch (config.getAppContextType()) {
+
+ case WEB_APPLICATION_CONTEXT:
+ AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
+ annotationConfigWebApplicationContext.scan(javaConfigBasePackages);
+ annotationConfigWebApplicationContext.setParent(parent);
+ annotationConfigWebApplicationContext.refresh();
+ return annotationConfigWebApplicationContext;
+
+ case APPLICATION_CONTEXT:
+ AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(javaConfigBasePackages);
+ annotationConfigApplicationContext.setParent(parent);
+ return annotationConfigApplicationContext;
+
+ }
+
+ throw new RuntimeException("This should never happen");
+
+ }
+
private void logNoSuchBeanDefinitionException(NoSuchBeanDefinitionException nsbde) {
if (LOG.isWarnEnabled()) {
LOG.warn("Skipping missing Spring bean: ", nsbde);