$30 off During Our Annual Pro Sale. View Details »

From Zero to Hero with Spring Boot (extended version)

From Zero to Hero with Spring Boot (extended version)

Spring Boot introduction (extended version, 2h format).

Stéphane Nicoll

May 08, 2015
Tweet

More Decks by Stéphane Nicoll

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    From Zero to Hero with Spring Boot
    Stéphane Nicoll
    Pivotal

    View Slide

  2. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Hello!
    2 @snicoll
    https://github.com/snicoll
    @snicoll
    [email protected]

    View Slide

  3. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    3 @snicoll

    View Slide

  4. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    4 @snicoll
    “ Spring Boot lets you pair-program with the Spring team.
    Josh Long, @starbuxman

    View Slide

  5. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Introduction to Spring Boot
    ! Single point of focus (as opposed to large collection of spring-* projects)
    ! A tool for getting started very quickly with Spring
    ! Common non-functional requirements for a "real" application
    ! Exposes a lot of useful features by default
    ! Gets out of the way quickly if you want to change defaults
    ! An opportunity for Spring to be opinionated
    5 @snicoll

    View Slide

  6. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    ಠ_ಠ Spring Boot is NOT
    ! A prototyping tool
    ! Only for embedded container apps
    ! Sub-par Spring experience
    ! For Spring beginners only
    6 @snicoll

    View Slide

  7. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Installation
    ! Requirements:
    • JDK6+
    • Maven 3.2+ / Gradle 1.12+
    ! Tools:
    • Spring Tool Suite (STS) - IntelliJ IDEA - Netbeans
    • Spring CLI (from https://start.spring.io or gvm)
    7 @snicoll

    View Slide

  8. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Let’s get started!
    8 @snicoll

    View Slide

  9. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Getting Started Really Quickly
    9 @snicoll
    @RestController
    public class HomeController {
    @Value("${conference.name:jsug}")
    private String conference;
    @RequestMapping("/")
    public String home() {
    return "Hello " + conference;
    }
    }

    View Slide

  10. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    First integration test
    10 @snicoll
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = DemoApplication.class)
    @WebIntegrationTest(randomPort = true)
    public class HomeControllerIntegrationTest {
    @Value("${local.server.port}")
    private int port;
    @Test
    public void runAndInvokeHome() {
    String url = "http://localhost:" + port + "/";
    String body = new RestTemplate()
    .getForObject(url, String.class);
    assertThat(body, is("Hello jsug"));
    }
    }

    View Slide

  11. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add Spring Data JPA
    11 @snicoll

    org.springframework.boot
    spring-boot-starter-data-jpa


    com.h2database
    h2
    runtime

    View Slide

  12. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add a Speaker entity
    12 @snicoll
    @Entity
    public class Speaker {
    @GeneratedValue
    @Id
    private Long id;
    private String firstName;
    private String lastName;
    private String twitter;
    @Column(columnDefinition = "TEXT")
    private String bio;
    public Speaker(String firstName, String lastName, String twitter) {
    // initialize attributes
    }
    // getters and setters
    }

    View Slide

  13. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add a Speaker Repository
    13 @snicoll
    public interface SpeakerRepository
    extends CrudRepository {
    Speaker findByTwitter(String twitter);
    Collection findByLastName(String lastName);
    }

    View Slide

  14. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Test that repository
    14 @snicoll
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = DemoApplication.class)
    public class SpeakerRepositoryTest {
    @Autowired
    private SpeakerRepository speakerRepository;
    @Test
    public void testFindByTwitter() throws Exception {
    Speaker stephane = speakerRepository.save(
    new Speaker("Stephane", "Nicoll", "snicoll"));
    assertThat(speakerRepository.findByTwitter("snicoll").getId(),
    is(stephane.getId()));
    }
    }

    View Slide

  15. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add Spring Data REST
    15 @snicoll

    org.springframework.boot
    spring-boot-starter-data-rest

    View Slide

  16. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    RESTful repository
    16 @snicoll
    public interface SpeakerRepository
    extends CrudRepository {
    @RestResource(path = "by-twitter")
    Speaker findByTwitter(@Param("id") String twitter);
    Collection findByLastName(@Param("name") String lastName);
    }

    View Slide

  17. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add Spring Security
    17 @snicoll

    org.springframework.boot
    spring-boot-starter-security

    View Slide

  18. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Spring Security config
    18 @snicoll
    @Configuration
    public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {
    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .withUser("hero").password("hero").roles("HERO", "USER").and()
    .withUser("user").password("user").roles("USER");
    }
    }

    View Slide

  19. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Fix our test
    19 @snicoll
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = DemoApplication.class)
    @WebIntegrationTest(randomPort = true)
    public class HomeControllerIntegrationTest {
    @Value("${local.server.port}")
    private int port;
    @Test
    public void runAndInvokeHome() {
    String url = "http://localhost:" + port + "/";
    String body = new TestRestTemplate("user", "user")
    .getForObject(url, String.class);
    assertThat(body, is("Hello jsug"));
    }
    }

    View Slide

  20. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add Spring Boot actuator
    20 @snicoll

    org.springframework.boot
    spring-boot-starter-actuator

    View Slide

  21. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add a health indicator
    21 @snicoll
    @Bean
    public HealthIndicator jsugHealthIndicator() {
    return () -> {
    if (new Random().nextBoolean()) {
    return Health.up().build();
    }
    else {
    return Health.down().withDetail("Boooo",42).build();
    }
    };
    }

    View Slide

  22. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add remote shell
    22 @snicoll

    org.springframework.boot
    spring-boot-remote-shell

    View Slide

  23. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add a speaker controller
    23 @snicoll
    @Controller
    public class SpeakerController {
    private final SpeakerRepository speakerRepository;
    @Autowired
    public SpeakerController(SpeakerRepository speakerRepository) {
    this.speakerRepository = speakerRepository;
    }
    @RequestMapping("/ui/speakers/{id}")
    public String show(@PathVariable Long id, ModelMap model) {
    Speaker speaker = speakerRepository.findOne(id);
    if (speaker == null) {
    throw new SpeakerNotFoundException();
    }
    model.put("speaker", speaker);
    return "speakers/show";
    }
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public static class SpeakerNotFoundException extends RuntimeException {
    }
    }

    View Slide

  24. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Create speaker show view
    24 @snicoll


    View speaker



    Stephane Nicoll

    Sample Biography.


    @snicoll




    View Slide

  25. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Best experience with PaaS
    ! Spring Boot features get a lot done for 12factor.net
    ! PaaS friendly: fast startup, devops oriented
    25 @snicoll
    $ mvn package
    $ cf push jsug -p target/jsug-0.0.1-SNAPSHOT.jar
    $ cf scale jsug -i 4

    View Slide

  26. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Starter POMs
    ! standard POM / gradle files: define dependencies
    ! many available: batch, integration, web, ampq…
    ! starter data-jpa = spring-data-jpa + hibernate
    26 @snicoll

    org.springframework.boot
    spring-boot-starter-web

    compile("org.springframework.boot:spring-boot-starter-web")

    View Slide

  27. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Writing your own starter
    ! Add support for X in Boot with a PR!
    ! Distribute a client lib in your company
    ! Standardize usage of component X in a platform
    ! [your use case here]
    27 @snicoll

    View Slide

  28. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Let’s write our own starter!
    28 @snicoll

    View Slide

  29. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    New auto-config project
    ! Create a new hello-service-auto-configuration project
    ! Only one mandatory dependency
    ! Should contain specific dependencies and auto-configuration classes
    29 @snicoll

    org.springframework.boot
    spring-boot-autoconfigure

    View Slide

  30. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add custom service interface
    ! This is the part that we’re trying to auto-configure
    ! In a typical use case, this interface comes from a 3rd party lib
    30 @snicoll
    public interface HelloService {
    String sayHello();
    }

    View Slide

  31. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Create a default implementation
    ! This default implementation will be shipped with the auto-config project but
    should not be used if the application provides one.
    31 @snicoll
    public class ConsoleHelloService implements HelloService {
    public String sayHello() {
    System.out.println("Hello Console");
    }
    }

    View Slide

  32. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Auto-configuration example
    32 @snicoll
    @Configuration
    @ConditionalOnClass(HelloService.class)
    public class HelloServiceAutoConfiguration {
    @ConditionalOnMissingBean
    @Bean
    public HelloService helloService() {
    return new ConsoleHelloService();
    }
    }

    View Slide

  33. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Declare the auto-configuration
    33 @snicoll
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    demo.hello.HelloServiceAutoConfiguration
    // one can order AutoConfigurations
    // with those annotations
    @AutoConfigureBefore
    @AutoConfigureAfter

    View Slide

  34. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add a dependency to our auto-configuration
    ! Add our auto-config project as a dependency in our main project
    34 @snicoll

    org.test.jsug
    hello-service-auto-configuration
    ...

    View Slide

  35. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Invoke our service when the application starts
    ! A Hello Service implementation is used on startup
    ! Running this will use the default implementation
    35 @snicoll
    @Component
    public class Startup implements CommandLineRunner {
    @Autowired private HelloService helloService;
    @Override
    public void run(String... args) throws Exception {
    helloService.sayHello();
    }
    }

    View Slide

  36. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Override default (auto-configured) implementation
    ! Add a @Bean definition in our DemoApplication class
    ! We provide our own implementation, so the default one won’t be created
    36 @snicoll
    @Bean
    public HelloService helloService() {

    return () ->
    LoggerFactory.getLogger(DemoApplication.class)
    .info("Hello from logs");

    }
    }

    View Slide

  37. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Add type-safe properties
    37 @snicoll
    @ConfigurationProperties("hello")
    public class HelloProperties {
    private String prefix = "Hello ";
    private String target;
    // getters and setters
    }

    View Slide

  38. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Enable properties support
    38 @snicoll
    @EnableConfigurationProperties(HelloProperties.class)
    @Configuration
    @ConditionalOnClass(HelloService.class)
    public class HelloServiceAutoConfiguration {

    View Slide

  39. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use type-safe properties
    39 @snicoll
    public class ConsoleHelloService implements HelloService {
    @Autowired
    private HelloProperties properties;
    @Override
    public void run(String... strings) throws Exception {
    System.out.println(properties.getPrefix() + " " +
    properties.getTarget());
    }
    }

    View Slide

  40. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Generate properties meta-data
    ! annotation processor that generates meta-data
    ! uses Javadoc to build keys descriptions
    ! default values detected
    ! manual declaration allowed
    40 @snicoll

    org.springframework.boot
    spring-boot-configuration-processor
    true

    View Slide

  41. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Document properties
    41 @snicoll
    @ConfigurationProperties("hello")
    public class HelloProperties {
    /**
    * Prefix of welcome message.
    */
    private String prefix = "Hello ";
    /**
    * Target of welcome message.
    */
    private String target;
    // getters and setters
    }

    View Slide

  42. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    https://spring.io powered by
    42 @snicoll
    github.com/spring-io/sagan

    View Slide

  43. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Links
    ! https://projects.spring.io/spring-boot/
    ! https://github.com/spring-projects/spring-boot
    ! https://spring.io/guides
    ! https://spring.io/blog
    ! https://spring.io/questions
    ! https://www.youtube.com/user/SpringSourceDev
    43 @snicoll
    @springboot @springcentral

    View Slide

  44. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    44
    Learn More. Stay Connected.
    ! Start your project at start.spring.io
    ! Getting started guides
    ! Follow @springboot
    ! StackOverflow - #spring-boot
    Twitter: twitter.com/springcentral
    YouTube: spring.io/video
    LinkedIn: spring.io/linkedin
    Google Plus: spring.io/gplus
    @snicoll

    View Slide