[bs-84] Add basic getting started guide to service project

Still work in progress, bubt enough there to get someone up a
nd running I hope
[#49047467]
This commit is contained in:
Dave Syer 2013-05-01 16:10:57 +01:00
parent bd79ec2362
commit ce0e443b0a
4 changed files with 252 additions and 1 deletions

View File

@ -11,6 +11,7 @@
<packaging>pom</packaging>
<properties>
<main.basedir>${project.basedir}/..</main.basedir>
<spring.bootstrap.version>0.0.1-SNAPSHOT</spring.bootstrap.version>
</properties>
<modules>
<module>spring-bootstrap-application</module>
@ -19,4 +20,81 @@
<module>spring-bootstrap-jpa-application</module>
<module>spring-bootstrap-web-application</module>
</modules>
</project>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.bootstrap</groupId>
<artifactId>spring-bootstrap</artifactId>
<version>${spring.bootstrap.version}</version>
</dependency>
</dependencies>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.bootstrap.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${start-class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,151 @@
<style>
table
{
border-collapse:collapse;
}
table,th, td
{
border: 1px solid black;
}
</style>
# Spring Bootstrap Services
Minimum fuss for getting RESTful services up and running in
production, and in other environments.
|Feature |Implementation |Notes |
|---|---|---|
|Server |Tomcat or Jetty | Whatever is on the classpath |
|REST |Spring MVC | |
|Security |Spring Security | If on the classpath |
|Logging |Logback, Log4j or JDK | Whatever is on the classpath. Sensible defaults. |
|Database |HSQLDB or H2 | Per classpath, or define a DataSource to override |
|Externalized configuration | Properties or YAML | Support for Spring profiles. Bind automatically to @Bean. |
|Validation | JSR-303 | |
|Management endpoints | Spring MVC | Health, basic metrics, request tracing, shutdown |
|Error pages | Spring MVC | Sensible defaults based on exception and status code |
|JSON |Jackson 2 | |
|ORM |Spring Data JPA | If on the classpath |
|Batch |Spring Batch | If enabled and on the classpath |
|Integration Patterns |Spring Integration | If on the classpath |
# Getting Started
You will need Java (6 at least) and a build tool (Maven is what we use
below, but you are more than wecome to use gradle). These can be
downloaded or installed easily in most operating systems. FIXME:
short instructions for Mac and Linux.
## A basic project
If you are using Maven create a really simple `pom.xml` with 2 dependencies:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>myproject</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.bootstrap</groupId>
<artifactId>spring-bootstrap-applications</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<spring.bootstrap.version>0.0.1-SNAPSHOT</spring.bootstrap.version>
<start-class>org.springframework.bootstrap.SpringApplication</start-class>
</properties>
<dependency>
<groupId>org.springframework.bootstrap</groupId>
<artifactId>spring-bootstrap-web-application</artifactId>
<version>${spring.bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.bootstrap</groupId>
<artifactId>spring-bootstrap-service</artifactId>
<version>${spring.bootstrap.version}</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
If you like Gradle, that's fine, and you will know what to do with
those co-ordinates. The first one adds Spring Bootstrap auto
configuration and the Jetty container to your application, and the
second one adds some more opinionated stuff like the default
management endpoints. If you prefer Tomcat FIXME: use a different
dependency.
You should be able to run it already:
$ mvn package
$ java -jar target/myproject-1.0.0-SNAPSHOT.jar
Then in another terminal
$ curl localhost:8080/healthz
ok
$ curl localhost:8080/varz
{"counter.status.200.healthz":1.0,"gauge.response.healthz":10.0,"mem":120768.0,"mem.free":105012.0,"processors":4.0}
`/healthz` is the default location for the health endpoint - it tells
you if the application is running and healthy. `/varz` is the default
location for the metrics endpoint - it gives you basic counts and
response timing data by default but there are plenty of ways to
customize it.
$ curl localhost:8080/
{"status": 404, "error": "Not Found", "message": "Not Found"}
That's OK, we haven't added any business content yet.
## Adding a business endpoint
To do something useful to your business you need to add at least one
endpoint. An endpoint can be implemented as a Spring MVC
`@Controller`, e.g.
@Controller
@EnableAutoConfiguration
public class SampleController {
@RequestMapping("/")
@ResponseBody
public Map<String, String> helloWorld() {
return Collections.singletonMap("message", "Hello World");
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleController.class, args);
}
}
You can launch that straight away using the Spring Bootstrap CLI
(without the `@EnableAutoConfiguration` and even without the import
statements that your IDE will add if you are using one), or you can
use the main method to launch it from your project jar. Just change
the `start-class` in the `pom` above to the fully qualified name of
your `SampleController`, e.g.
<start-class>com.mycompany.sample.SampleController</start-class>
and re-package:
$ mvn package
$ java -jar target/myproject-1.0.0-SNAPSHOT.jar
$ curl localhost:8080/
{"message": "Hello World"}
# Add a database
Just add `spring-jdbc` and an embedded database to your dependencies:
FIXME: TBD

View File

@ -27,6 +27,9 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.bootstrap.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.bootstrap.autoconfigure.data.JpaRepositoriesAutoConfiguration;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
@ -608,4 +611,13 @@ public class SpringApplication {
}
public static void main(String[] args) {
run(new Class<?>[] { AutoMain.class }, args);
}
@EnableAutoConfiguration(exclude = { JpaRepositoriesAutoConfiguration.class,
BatchAutoConfiguration.class })
public static class AutoMain {
}
}

View File

@ -26,6 +26,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.bootstrap.SpringApplication.AutoMain;
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.context.ApplicationContext;
@ -152,6 +153,15 @@ public class SpringApplicationTests {
assertThat(getEnvironment().getProperty("foo"), equalTo("bar"));
}
@Test
public void emptytApplicationContext() throws Exception {
// This is the class that will be used for main()
SpringApplication application = new SpringApplication(AutoMain.class);
this.context = application.run();
assertThat(this.context,
instanceOf(AnnotationConfigEmbeddedWebApplicationContext.class));
}
@Test
public void defaultApplicationContext() throws Exception {
SpringApplication application = new SpringApplication(ExampleConfig.class);