Dlaczego Spring Boot 2.0 to przełomowy moment?
Spring Boot 2.0 to nie zwykła aktualizacja – to kompletna modernizacja platformy. Podobnie jak przejście z Java 7 na 8 zmieniło sposób pisania kodu, Spring Boot 2.0 wprowadza reactive programming, lepsze performance i nowoczesne podejście do configuration. To inwestycja w przyszłość Java ecosystem na następne 5 lat.
Co się nauczysz:
- Breaking changes i wymagania migracji z Boot 1.x
- Reactive programming z Spring WebFlux
- Nowe Actuator endpoints i metryki
- Zmiany w Spring Security auto-configuration
- Ulepszone configuration properties i validation
Kluczowe breaking changes
Java 8 jako minimum requirement
Spring Boot 2.0 wymaga minimum Java 8, co pozwala na pełne wykorzystanie lambda expressions, Optional, Stream API i innych Java 8 features w całym framework.
1.8 2.0.0.M7 org.springframework.boot spring-boot-starter-parent 2.0.0.M7
Nowa architektura dependency management
Komponent | Spring Boot 1.5 | Spring Boot 2.0 | Impact |
---|---|---|---|
Spring Framework | 4.3.x | 5.0.x | Reactive support, Java 8 APIs |
Hibernate | 5.0.x | 5.2.x | JPA 2.1 improvements |
Jackson | 2.8.x | 2.9.x | Java 8 time support |
Tomcat | 8.5.x | 8.5.x/9.0.x | HTTP/2 support |
Reactive Programming z Spring WebFlux
Największa nowość w Spring Boot 2.0 to pełne wsparcie dla reactive programming przez Spring WebFlux – alternatywę dla tradycyjnego Spring MVC.
WebFlux vs MVC – kiedy używać czego?
// Tradycyjny Spring MVC Controller @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public ResponseEntitygetUser(@PathVariable Long id) { User user = userService.findById(id); // Blocking call return ResponseEntity.ok(user); } @GetMapping public List getAllUsers() { return userService.findAll(); // Blocking, loads all to memory } }
// Reactive WebFlux Controller @RestController @RequestMapping("/api/reactive/users") public class ReactiveUserController { @Autowired private ReactiveUserService userService; @GetMapping("/{id}") public Mono> getUser(@PathVariable Long id) { return userService.findById(id) // Non-blocking .map(ResponseEntity::ok) .defaultIfEmpty(ResponseEntity.notFound().build()); } @GetMapping public Flux getAllUsers() { return userService.findAll(); // Streaming, handles backpressure } @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux streamUsers() { return userService.findAll() .delayElements(Duration.ofSeconds(1)); // Server-Sent Events } }
Reactive dependencies
org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-mongodb-reactive org.springframework.boot spring-boot-starter-data-redis-reactive
Functional routing jako alternatywa
@Configuration public class RouterConfiguration { @Bean public RouterFunctionuserRoutes(UserHandler userHandler) { return RouterFunctions .route(GET("/api/functional/users/{id}"), userHandler::getUser) .andRoute(GET("/api/functional/users"), userHandler::getAllUsers) .andRoute(POST("/api/functional/users"), userHandler::createUser) .andRoute(PUT("/api/functional/users/{id}"), userHandler::updateUser); } } @Component public class UserHandler { @Autowired private ReactiveUserService userService; public Mono getUser(ServerRequest request) { Long id = Long.valueOf(request.pathVariable("id")); return userService.findById(id) .flatMap(user -> ServerResponse.ok().bodyValue(user)) .switchIfEmpty(ServerResponse.notFound().build()); } public Mono getAllUsers(ServerRequest request) { return ServerResponse.ok() .contentType(MediaType.APPLICATION_JSON) .body(userService.findAll(), User.class); } }
Actuator 2.0 – kompletnie przepisany
Nowa architektura endpoints
Actuator został kompletnie przepisany z focus na security, performance i pluggability:
Endpoint | Boot 1.5 URL | Boot 2.0 URL | Changes |
---|---|---|---|
Health | /health | /actuator/health | Detailed health indicators |
Metrics | /metrics | /actuator/metrics | Micrometer integration |
Info | /info | /actuator/info | Git info auto-configuration |
Env | /env | /actuator/env | Better property masking |
Konfiguracja Actuator 2.0
# application.yml - Actuator 2.0 configuration management: endpoints: web: base-path: /management # Zmiana base path exposure: include: health,info,metrics,env # Explicit exposure exclude: shutdown endpoint: health: show-details: when-authorized # Security-aware show-components: always metrics: enabled: true metrics: tags: application: myapp # Custom tags environment: ${spring.profiles.active}
Micrometer integration
@RestController public class MetricsController { private final MeterRegistry meterRegistry; private final Counter userCreationCounter; private final Timer requestTimer; public MetricsController(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; this.userCreationCounter = Counter.builder("user.creation") .description("Number of users created") .tag("type", "registration") .register(meterRegistry); this.requestTimer = Timer.builder("http.requests") .description("HTTP request duration") .register(meterRegistry); } @PostMapping("/users") public ResponseEntitycreateUser(@RequestBody User user) { return Timer.Sample.start(meterRegistry) .stop(requestTimer, () -> { User savedUser = userService.save(user); userCreationCounter.increment(); return ResponseEntity.ok(savedUser); }); } }
Spring Security – nowa auto-configuration
Breaking changes w Security
Spring Boot 2.0 znacznie zmienia domyślną konfigurację security:
// Spring Boot 1.5 - domyślne zachowanie // Wszystkie endpoints zabezpieczone basic auth // User: user, password: generowane w logach // Spring Boot 2.0 - nowe domyślne zachowanie @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // Actuator endpoints mają osobną konfigurację http.authorizeRequests() .requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll() .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR") .anyRequest().authenticated() .and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // Nowy sposób konfiguracji in-memory users auth.inMemoryAuthentication() .withUser("user") .password("{noop}password") // {noop} = no encoding .roles("USER") .and() .withUser("actuator") .password("{noop}actuator") .roles("ACTUATOR"); } }
OAuth 2.0 i JWT improvements
# application.yml - OAuth 2.0 client configuration spring: security: oauth2: client: registration: google: client-id: ${GOOGLE_CLIENT_ID} client-secret: ${GOOGLE_CLIENT_SECRET} scope: openid,profile,email github: client-id: ${GITHUB_CLIENT_ID} client-secret: ${GITHUB_CLIENT_SECRET} scope: read:user,user:email provider: google: authorization-uri: https://accounts.google.com/o/oauth2/auth token-uri: https://accounts.google.com/o/oauth2/token user-info-uri: https://www.googleapis.com/oauth2/v1/userinfo
Configuration Properties overhaul
Relaxed binding 2.0
// Spring Boot 2.0 - ulepszone @ConfigurationProperties @ConfigurationProperties(prefix = "myapp") @Validated public class MyAppProperties { @NotNull @Size(min = 1, max = 100) private String applicationName; @Valid private Database database = new Database(); @Valid private List<@Valid Server> servers = new ArrayList<>(); // Nested configuration classes public static class Database { @NotBlank private String url; @Min(1) @Max(1000) private int maxConnections = 10; @DurationUnit(ChronoUnit.SECONDS) private Duration connectionTimeout = Duration.ofSeconds(30); // getters/setters } public static class Server { @NotBlank private String host; @Min(1024) @Max(65535) private int port; // getters/setters } }
# application.yml - Configuration properties myapp: application-name: My Application database: url: jdbc:postgresql://localhost/mydb max-connections: 50 connection-timeout: 45s # Duration support servers: - host: server1.example.com port: 8080 - host: server2.example.com port: 8081
Migracja z Spring Boot 1.x
Migration checklist
- Java 8+ requirement – upgrade JVM version
- Dependencies update – check compatibility matrix
- Actuator endpoints – update URLs w testach i monitoring
- Security configuration – review custom security config
- Configuration properties – validate binding changes
- Metrics – migrate custom metrics do Micrometer API
Typowe problemy podczas migracji
// Problem: Spring Boot 1.5 metrics API przestaje działać // Stary kod @Autowired private CounterService counterService; counterService.increment("user.registration"); // Rozwiązanie: Migracja na Micrometer @Autowired private MeterRegistry meterRegistry; Counter.builder("user.registration") .register(meterRegistry) .increment();
Performance improvements
Startup time optimization
Obszar | Improvement | Impact |
---|---|---|
Bean creation | Lazy initialization support | Faster startup |
Classpath scanning | Indexed components | Reduced reflection |
Auto-configuration | Conditional optimization | Less overhead |
Reactive stack | Non-blocking I/O | Better resource utilization |
Memory usage optimizations
# application.yml - Performance tuning spring: main: lazy-initialization: true # Boot 2.2+ feature preview jpa: hibernate: ddl-auto: none # Don't scan entities on startup open-in-view: false # Disable OSIV for better performance jackson: serialization: write-dates-as-timestamps: false
Nie od razu. Spring Boot 1.5 będzie wspierane do sierpnia 2019. Zaplanuj migrację w spokojnym tempie, szczególnie jeśli masz dużą aplikację z custom security configuration.
Nie, oba stacki będą współistnieć. Reactive jest lepszy dla high-throughput, I/O-heavy applications. Tradycyjny MVC nadal lepszy dla CRUD applications i zespołów bez reactive experience.
Użyj Spring Boot’s dependency management i sprawdź release notes. Większość Spring ecosystem libraries ma wersje kompatybilne z Boot 2.0. Sprawdź również migration guide na spring.io.
Nie, URL paths się zmieniły (/health → /actuator/health) i security model jest inny. Musisz update monitoring tools i health check URLs w load balancerach.
Spring Cloud Finchley będzie pierwszą wersją kompatybilną z Boot 2.0. Obecnie (luty 2017) Spring Cloud działa z Boot 1.5.x. Čekaj na Finchley release train.
🚀 Zadanie dla Ciebie
Eksperymentuj z Spring Boot 2.0 milestone releases:
- Utwórz nową aplikację z spring-boot-starter-webflux
- Zaimplementuj reactive controller z Mono/Flux endpoints
- Skonfiguruj custom Actuator endpoint z Micrometer metrics
- Dodaj OAuth 2.0 client configuration dla Google/GitHub
- Porównaj performance z equivalent Spring MVC application
- Test reactive database operations z reactive MongoDB
Dokumentuj różnice w performance i developer experience między reactive a traditional stack.
Przydatne zasoby:
- Official Spring Boot 2.0 Migration Guide
- Spring Boot 2.0.0.M7 Release Notes
- Spring WebFlux Documentation
- Micrometer Documentation
Planujesz już migrację na Spring Boot 2.0? Które nowe features wydają ci się najbardziej przydatne w twoich projektach?