Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Boot Loot

255 views

Published on

Spring Boot tips & tricks as presented at Spring I/O 2019.
Code is at https://github.com/jkuipers/bootloot

Published in: Software
  • Be the first to comment

Boot Loot

  1. 1. Joris Kuipers @jkuipers Boot Loot!
  2. 2. About Me  Joris Kuipers  @jkuipers  CTO, hands-on architect and fly-by-night Spring trainer @ Trifork Amsterdam
  3. 3. What’s In The Box?  Tips & tricks for Boot applications  Based on production experience  And too much time spent w/ Spring  Up your game and Spring like the pros!
  4. 4. Spring-MVC Default Errors “It is a true man's part not to err, but it is also noble of a man to perceive his error.” ― Apollonius of Tyana
  5. 5. Spring Boot Default Error Page  Rendered for uncaught exceptions  Browsers: HTML, other HTTP clients: JSON  Let’s look at default for binding/validation errors from MVC Controllers
  6. 6. What’s Happening?  Binding-/validation errors cause FieldErrors  extending DefaultMessageSourceResolvable  which are marshalled as-is
  7. 7. Wouldn’t It Be Nice…  … if these error codes were in fact resolved?  Solution: custom ErrorAttributes
  8. 8. Using Custom @ConfigurationProperties “Custom is second nature” ― Saint Augustine
  9. 9. @ConfigurationProperties  Boot-feature to bind config values to Java bean  For config keys sharing common prefix  Consume through dependency injection  Let’s look at an example
  10. 10.  Groups related properties, easy access  Nice, but just like @Value("${loot.game}")  IDE Support  Validation Let’s have a look Benefits
  11. 11. @ConfigurationProperties summary  Discovering available configuration  Especially nice in big projects  or when using shared libraries with auto- configuration  Validating configuration  Exposed by /configprops actuator endpoint  Will be auto-scanned in Boot 2.2
  12. 12. What About Relaxed Binding?  E.g. loot.allow-transfer or LOOT_ALLOW_TRANSFER for allowTransfer property  Required configuration properties with Boot 1.x  Since Boot 2, works everywhere  By using kebab casing  @Value("${loot.allow-transfer}")
  13. 13. Reducing Metrics Cardinality “For the wise man looks into space and he knows there is no limited dimensions.” ― Zhuangzi
  14. 14. Micrometer.io Metrics  Boot apps can collect & expose metrics  Metric: value + associated key-values  Dimensions / tags  Example: http.client.requests  Timer, plus info on HTTP method, status, URI, etc.
  15. 15. Dimension Cardinality  Single dimension can have multiple values  Not useful if range is too big  Won’t even work  Let’s look at an example
  16. 16. Reducing Dimension Cardinality  First of all: use APIs as intended  E.g. RestTemplate with URI Template variables  However, not always possible / the solution  Micrometer API allows post-processing filters  Inspect and change tag values to limit nr of options
  17. 17. Builders and Customizers “Believe me, that was a happy age, before the days of architects, before the days of builders.” ― Lucius Annaeus Seneca
  18. 18. Spring Boot Builders  Many common helpers in Spring apps  RestTemplate, Jackson ObjectMappers, …  Often created in code or @Bean methods directly @Bean RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); // ... return restTemplate; }
  19. 19. Contributing Instrumentation  Spring frameworks or custom libraries often need to instrument code  RestTemplate interceptors for metrics, distributed tracing or service discovery  MockMvc setup for Security or RestDocs support  How to apply dynamically to all instances?
  20. 20. Builders and Customizers  Common pattern: create a builder  Autoconfigured singleton Spring Bean  Inject builder with customizers  Other beans, wired by type  Contribute configuration: either on the builder or on the result of the builder  Use the builder to get instance of helper
  21. 21. Opiniated Builders  Builders can provide own default config  Allows Boot-specific opiniated defaults  And additional auto-configuration  Examples:  Jackson ObjectMapper ignores unknown fields, registers modules  RestTemplate using Apache or “Ok” HTTP client
  22. 22. Builder Example: RestTemplateBuilder  Set up in RestTemplateAutoConfiguration  Injected with RestTemplateCustomizers  Which are provided by many frameworks  E.g. micrometer.io integration, Spring Cloud  Let’s see this in action
  23. 23. But what about…  Sleuth distributed tracing?  That works without builder!  Uses BeanPostProcessor to register interceptor  Works for this case, not generic solution  E.g. target might be immutable  Still requires RestTemplate to be a Spring bean
  24. 24. Customizer Examples  Jackson OffsetDateTime marshalling @Bean Jackson2ObjectMapperBuilderCustomizer offsetDateTimeSerializerCustomizer() { return objectMapperBuilder -> objectMapperBuilder.serializerByType( OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() { public void serialize(OffsetDateTime value, JsonGenerator generator, SerializerProvider sp) throws IOException { generator.writeString( value.truncatedTo(SECONDS).format(ISO_OFFSET_DATE_TIME)); } }); }
  25. 25. Local Developer Configuration “We believe in global scalability with local relevance.” ― Gillian Tans
  26. 26. Local Development Configuration  Setup for local development often differs  Different config properties  Security disabled, or with hardcoded users  No cloud-based services  How to ensure easy setup for all devs?
  27. 27. “Local” Spring Profile  Solution: define “local” Spring profile  Specific configuration files  E.g. application-local.properties  Local-specific Spring beans configuration
  28. 28. How to enable “local” profile  Typical way to enable profiles: spring.profiles.active property  Comma-separated list  Must be active for all local services  Per-service run config is tedious and error-prone  Solution: use OS environment variable!  SPRING_PROFILES_ACTIVE
  29. 29. Orthogonal Profiles  What if you want to use other profiles as well?  Can’t use two different spring.profiles.active properties  Will override, not merge  Solution: use SPRING_PROFILES_INCLUDE env var  Binds to spring.profiles.include  Will add, not override
  30. 30. Examples of Local Config  Unique port(s) per service  Connection settings  Security  Actuator web endpoints enabling / config  Disabling micrometer.io metrics bindings  Disabling Spring Cloud central configuration
  31. 31. Local Logging Setup Through application-local.properties:  Hide some of the Sleuth noise logging.pattern.level=%5p [%X{traceId:-}]  Change log levels for development logging.level.org.springframework.ws.client. MessageTracing=TRACE
  32. 32. Adding external directories to fat JAR’s classpath “But we try to pretend, you see, that the external world exists altogether independently of us.” ― Alan Watts
  33. 33. External Classpath Resources  Non-Boot apps often read resources from external classpath directories  Config files, keystores, resource bundles, …  Allows for easy updating on the one hand  And location-transparency in code on the other
  34. 34. External Classpath Dirs with Spring Boot  Becomes a problem when migrating to Boot’s fat jar  Classpath only within jar  Lots of work to rewrite all code (incl. libs)
  35. 35. Spring Boot Launchers  Boot apps use a launcher  Default launcher can be overridden  Configure layout through build plugin <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <layout>ZIP</layout> </configuration> </plugin>
  36. 36. PropertiesLauncher  Configured as Main-Class in MANIFEST.MF  Loads settings from a loader.properties, manifest or environment variables  Supports adding directories to the classpath  Via loader.path property
  37. 37. Conclusion  Boot is awesome  Doesn’t mean just use as-is  Plenty of customization options  It pays off to read documentation and visit Spring conferences ;)  https://github.com/jkuipers/bootloot
  38. 38. We’re Hiring!
  39. 39. Joris Kuipers @jkuipers Thanks! Q&A
  40. 40. Bonus contents (wait, there’s more?)
  41. 41. Custom Auto-configuration “Sometimes, magic is just someone spending more time on something than anyone else might reasonably expect.” ― Teller
  42. 42. Auto-Configuration  Best known Spring Boot feature  Condition configuration classes, evaluated at startup  After your own config classes  Can be great for custom libraries as well  Micro-services  Inter-project
  43. 43. Write Your Own Auto-Configuration  Create a Java library  Add one or more @Configuration classes  List them in a META-INF/spring.factories file  Under key org.springframework.boot.autoconfigure. EnableAutoConfiguration
  44. 44. Examples  Logging  MDC setup, Sleuth overrides  Metrics  Shared custom tags, cardinality reduction filters, exposing trace IDs in responses, accepting external trace IDs  HTTP Client  Custom HTTP client setup, RestTemplate setup  MVC  Custom ErrorAttributes, shared ControllerAdvice
  45. 45. Caveats  Consider interaction with Boot’s auto-config  Use @AutoConfigureBefore/-After where needed  Allow overrides and disabling selectively

×