Spring Boot

ExMachina

by Davide Angelocola

announced in August 2013

simpler getting started experience

non-functional requirements (e.g. monitoring, logging)

an opinionated framework on top of Spring

no XML config, @Component, @Autowired

reduces boilerplate configuration

ready to use integrations such as websocket, mail, JPA, elasticsearch

reuse best practices

documentation (epub, pdf, html)

No code generation

vs spring-roo or Yeoman

Gradle, CLI, Cloud

* I never used them

Maven: parent POM

dependencyManagement, exclusions, scopes




    4.0.0
    ch.exmachina
    myapp
    0.0.1-SNAPSHOT
    
        org.springframework.boot
        spring-boot-starter-parent
        1.4.1.RELEASE
    
    

					

Maven: plugin

run a project with mvn spring-boot:run

hot deploy of resources and Java classes (* with some restrictions)

Library

autoconfigure Spring components (mvc, jdbc, tx, etc)



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

						

@Controller
@EnableAutoConfiguration
public class SampleController {

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }
}

based on @Conditional

* introduced in Spring 4.0


@Bean
@Conditional(OnWindows.class)
public LockingService lockingService() {
    return new WindowsLockingService();
}

public class OnWindows implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      Environment env = context.getEnvironment();
      return env.getProperty("os.name").contains("Windows");
    }

}

						
  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean
  • @ConditionalOnProperty
  • @ConditionalOnExpression

begin without custom configuration

e.g. JDBC datasource with pooling, transaction management, flyway



    org.springframework.boot
    spring-boot-starter-jdbc

						

easily allows replacements gradually replacing auto-configuration

Testing

configures junit, spring-test, JSONAssert, hamcrest, ...


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

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void exampleTest() {
        String body = restTemplate.getForObject("/", String.class);
        assertThat(body).isEqualTo("Hello World");
    }

}

Operations

strong separation between code and configuration

properties


@Value("${foo.service.port}")
int port;

stronly-typed properties


@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {

    @javax.validation.constraints.NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}

Externalize configuration

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
  2. @TestPropertySource annotations on your tests.
  3. @SpringBootTest#properties annotation attribute on your tests.
  4. Command line arguments.
  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
  6. ServletConfig init parameters.
  7. ServletContext init parameters.
  8. JNDI attributes from java:comp/env.
  9. Java System properties (System.getProperties()).
  10. OS environment variables.
  11. A RandomValuePropertySource that only has properties in random.*.
  12. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
  13. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
  14. Application properties outside of your packaged jar (application.properties and YAML variants).
  15. Application properties packaged inside your jar (application.properties and YAML variants).
  16. @PropertySource annotations on your @Configuration classes.
  17. Default properties (specified using SpringApplication.setDefaultProperties).
customizable properties

Enabling CORS


endpoints.cors.allowed-origins=http://example.com
endpoints.cors.allowed-methods=GET,POST

HTTP compression


server.compression.enabled=true

No servlet container, just an executable jar

servlet container is embedded (apache-tomcat, jetty, undertow)


root@host# ln -s /opt/myapp/myapp.jar /etc/init.d/myapp
root@host# service myapp start
						

can be built as .war as well

for servlet 3.x containers (Cantone)

for servlet 2.5 containers (EOC) using web.xml and spring-boot-legacy

Actuator

information

healthchecks

metrics

Logging

logback by default

configurable via properties/YAML

file, rotation, etc

Problems

It's all magic (by design)

--debug to the rescue:

  • classpath
  • matching autoconfigurations
  • non-matching autoconfigurations
  • excluded autoconfigurations

2016-10-14 10:17:59.134 ERROR 43374 --- o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method exportingRepository in ch.eoc.cic.web.api.PersistenceDevelopmentConfig
required a bean of type 'org.springframework.jdbc.core.JdbcOperations' that could not be found.
	- Bean method 'jdbcTemplate' not loaded because @ConditionalOnSingleCandidate
      (types: javax.sql.DataSource; SearchStrategy: all) did not find any beans
						

autoconfiguration of security is too simple

cannot use JSP with embedded tomcat

* use freemarker

No silver bullets™

  • file-archiver standalone app with camel, maven-appassembler, custom configurations
  • ger-services webapp, jetty locally, tomcat 6.x on prod
  • generisk webapp, jetty locally, tomcat 6.x on prod

Standardization

more uniform projects

less effort in infrastructure

deploy documentation for free

END;