pratiktest
10/1/2016 - 4:28 PM

spring.md

Spring Boot

Requirements

  • jdk 1.8+
  • maven 3.0+ /gradle 2.3+
  • for maven in pom.xml include parent as
    • org.springframework.boot spring-boot-starter-parent 1.4.1.RELEASE
  • get the spring boot dependency
    • org.springframework.boot spring-boot-starter-web
  • install spring boot plugin for maven
    • org.springframework.boot spring-boot-maven-plugin

what is spring boot maven plugin

  • Spring boot maven plugin provides
    • it collects all jars in classpath and creates an uber jar. So you can easily execute your service and transport it
    • it searches for public static void main class to run from
    • it has a build in depedency resolver which will override dependencies to match dependencies compatible with spring boot. (This will override the dependency set by us, maybe a problem since we cannot be sure if spring overrode version we set)

what can i do with spring boot?

  • Spring boot automatically configures embedded tomcat (servlet container)
  • If you want jetty we can configure embedded jetty

Rest controller

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }

}
  • @RestController combines @Controller and @ResponseBody to give us back

SpringBootApplication

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }

}
  • Spring boot application combines @ComponentScan, @Configuration, @EnableSpringMvc ( if spring-webmvc is in classpath, This will setup the dispatcherServlet (Servlet over httpServlet following servelt spec to handle http request and dispatch web requests, provide mapping and handle exceptions) @EnableAutoConfiguration. (Do we really want component scan always?)
  • Note there is no web.xml , instead @SpringBootApplication uses SpringApplication.run() to launch application. Its pure java. The deployment description is embedded into code and spring determines it. (maybe not recommended)

Unit tests

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
  • MockMvc it comes from spring test dependency. It sets builder classes to send http requests to dispatcher servlet. To Autowire mockMvc we need @SpringBootTest and @AutoConfigureMockMvc
  • This just sends a fake http request to dispacther servlet.. above it is sending stuff to dispatcher servlet and then aserting the response
  • note since we do not start the server , this is a unit test for resource
  • drawback is lot of annotations

Integration tests

package hello;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;

import java.net.URL;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {

    @LocalServerPort
    private int port;

    private URL base;

    @Autowired
    private TestRestTemplate template;

    @Before
    public void setUp() throws Exception {
        this.base = new URL("http://localhost:" + port + "/");
    }

    @Test
    public void getHello() throws Exception {
        ResponseEntity<String> response = template.getForEntity(base.toString(),
                String.class);
        assertThat(response.getBody(), equalTo("Greetings from Spring Boot!"));
    }
}
  • embedded server is started on random port, by arguments of annotation @SpringBootTest
  • we can discover the port at runtime using @LocalServerPort annotation

Management end points by spring boot

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • after adding the above dependency do the below
mvn package && java -jar target/gs-spring-boot-0.1.0.jar
  • its easy to check health of app
curl localhost:8080/health
  • add endpoints.shutdown.enabled=true to application.properties to enable /shutdown endpoint

spring-boot-starter links

spring boot starter

what is jmx

  • jmx is java management extension. It has api to get monitoring and management information for java. We can use a jmx client and query programtically monitoring information.