Sie sind auf Seite 1von 44

From Zero to Hero with Spring Boot

Stphane Nicoll
Pivotal
Unless otherwise indicated, these slides are 2013-2014Pivotal Software, Inc. and licensedunder a

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

Hello!

@snicoll
https://github.com/snicoll
snicoll@pivotal.io

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Spring Boot lets you pair-program with the Spring team.

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

Josh Long, @starbuxman

@snicoll

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

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

_ Spring Boot is NOT

!
!
!
!

A prototyping tool
Only for embedded container apps
Sub-par Spring experience
For Spring beginners only

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

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)

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Lets get started!

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Getting Started Really Quickly

@RestController
public class HomeController {
@Value("${conference.name:jsug}")
private String conference;
@RequestMapping("/")
public String home() {
return "Hello " + conference;
}
}
9

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

First integration test


@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"));
}
}

10

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add Spring Data JPA

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

11

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add a Speaker entity


@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
}
12

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add a Speaker Repository

public interface SpeakerRepository


extends CrudRepository<Speaker, Long> {
Speaker findByTwitter(String twitter);
Collection<Speaker> findByLastName(String lastName);
}

13

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Test that repository


@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()));
}
}

14

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add Spring Data REST

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

15

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

RESTful repository

public interface SpeakerRepository


extends CrudRepository<Speaker, Long> {
@RestResource(path = "by-twitter")
Speaker findByTwitter(@Param("id") String twitter);
Collection<Speaker> findByLastName(@Param("name") String lastName);
}

16

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add Spring Security

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

17

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Spring Security config

@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");
}
}

18

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Fix our test


@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"));
}
}
19

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add Spring Boot actuator

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

20

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add a health indicator


@Bean
public HealthIndicator jsugHealthIndicator() {
return () -> {
if (new Random().nextBoolean()) {
return Health.up().build();
}
else {
return Health.down().withDetail("Boooo",42).build();
}
};
}

21

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add remote shell

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-remote-shell</artifactId>
</dependency>

22

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add a speaker controller


@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 {
}
}
23

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Create speaker show view

<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${speaker.firstName} + ' ' + ${speaker.lastName}">View speaker</title>
</head>
<body>
<div class="profile">
<h1 class="name" th:text="${speaker.firstName} + ' ' + ${speaker.lastName}">Stephane Nicoll</h1>
<div>
<p th:text="${speaker.bio}">Sample Biography.</p>
</div>
<div>
<a th:href="'http://twitter.com/' + ${speaker.twitter}" class="twitter" th:text="'@' + $
{speaker.twitter}">@snicoll</a>
</div>
</div>
</body>
</html>

24

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Best experience with PaaS

$ mvn package
$ cf push jsug -p target/jsug-0.0.1-SNAPSHOT.jar
$ cf scale jsug -i 4

! Spring Boot features get a lot done for 12factor.net


! PaaS friendly: fast startup, devops oriented

25

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Starter POMs
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
compile("org.springframework.boot:spring-boot-starter-web")

! standard POM / gradle files: define dependencies


! many available: batch, integration, web, ampq
! starter data-jpa = spring-data-jpa + hibernate

26

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

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

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Lets write our own starter!

28

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

New auto-config project

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

! Create a new hello-service-auto-configuration project


! Only one mandatory dependency
! Should contain specific dependencies and auto-configuration classes

29

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add custom service interface

public interface HelloService {


String sayHello();
}

! This is the part that were trying to auto-configure


! In a typical use case, this interface comes from a 3rd party lib

30

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Create a default implementation

public class ConsoleHelloService implements HelloService {


public String sayHello() {
System.out.println("Hello Console");
}
}

! This default implementation will be shipped with the auto-config project but
should not be used if the application provides one.
31

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Auto-configuration example
@Configuration
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {
@ConditionalOnMissingBean
@Bean
public HelloService helloService() {
return new ConsoleHelloService();
}
}
32

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Declare the auto-configuration

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
demo.hello.HelloServiceAutoConfiguration

// one can order AutoConfigurations


// with those annotations
@AutoConfigureBefore
@AutoConfigureAfter

33

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add a dependency to our auto-configuration

<dependency>
<groupId>org.test.jsug</groupId>
<artifactId>hello-service-auto-configuration</artifactId>
<version>...</version>
</dependency>

! Add our auto-config project as a dependency in our main project

34

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Invoke our service when the application starts


@Component
public class Startup implements CommandLineRunner {
@Autowired private HelloService helloService;
@Override
public void run(String... args) throws Exception {
helloService.sayHello();
}
}

! A Hello Service implementation is used on startup


! Running this will use the default implementation
35

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Override default (auto-configured) implementation

@Bean
public HelloService helloService() {
return () ->
LoggerFactory.getLogger(DemoApplication.class)
.info("Hello from logs");
}
}

! Add a @Bean definition in our DemoApplication class


! We provide our own implementation, so the default one wont be created
36

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Add type-safe properties

@ConfigurationProperties("hello")
public class HelloProperties {
private String prefix = "Hello ";
private String target;
// getters and setters
}

37

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Enable properties support

@EnableConfigurationProperties(HelloProperties.class)
@Configuration
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {

38

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Use type-safe properties


public class ConsoleHelloService implements HelloService {
@Autowired
private HelloProperties properties;
@Override
public void run(String... strings) throws Exception {
System.out.println(properties.getPrefix() + " " +
properties.getTarget());
}
}
39

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Generate properties meta-data


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

! annotation processor that generates meta-data


! uses Javadoc to build keys descriptions
! default values detected
! manual declaration allowed
40

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Document properties
@ConfigurationProperties("hello")
public class HelloProperties {
/**
* Prefix of welcome message.
*/
private String prefix = "Hello ";
/**
* Target of welcome message.
*/
private String target;
// getters and setters
}
41

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

https://spring.io powered by

github.com/spring-io/sagan

42

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

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

@springboot

43

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@springcentral
@snicoll

Learn More. Stay Connected.

! Start your project at start.spring.io

Twitter: twitter.com/springcentral

! Getting started guides

YouTube: spring.io/video

! Follow @springboot

LinkedIn: spring.io/linkedin

! StackOverflow - #spring-boot

Google Plus: spring.io/gplus

44

Unless otherwise indicated, these slides are 2013-2015Pivotal Software, Inc. and licensedunder a

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

@snicoll

Das könnte Ihnen auch gefallen