Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
dhiraj_jaiswal
Advisor
Advisor
2,101
  • SAP Managed Tags:
Introduction: Spring Boot 3.0 will require Java 17 and spring framework 6 hence it becomes important for developers to get familiar with the changes and enhancements done in spring libraries as well as third-party library to adopt the new technology as part of best practices. In this blog I have tried to cover recent enhancements that are done in spring project using which code base can be simplified and developer experience can be improved.

Spring Framework 6 changes



Validator factory: A functional approach to using validator.


Introduction of method in Validator to provide a way to create a validator for the specific type <T> and define the validator in a functional way. reference


package com.example.validatingforminput;

import am.ik.yavi.builder.ValidatorBuilder;
import am.ik.yavi.core.Validator;

public class PersonForm {

public static Validator<PersonForm> validator = ValidatorBuilder.<PersonForm>of()
.constraint(PersonForm::getName, "name", c -> c.notNull().greaterThanOrEqual(2).lessThanOrEqual(30))
.constraint(PersonForm::getAge, "age", c -> c.notNull().greaterThanOrEqual(18))
.build();

// ...
}

package com.example.validatingforminput;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;


@Controller
public class WebController {

@InitBinder
void initBinder(WebDataBinder binder) {
Validator personValidator = Validator.forInstanceOf(PersonForm.class, PersonForm.validator.toBiConsumer(Errors::rejectValue));
binder.addValidators(personValidator);
}

@GetMapping("/")
public String showForm(PersonForm personForm) {
return "form";
}

@PostMapping("/")
public String checkPersonInfo(@Validated PersonForm personForm, BindingResult bindingResult) {

if (bindingResult.hasErrors()) {
return "form";
}

return "redirect:/results";
}
}


New methods in DataAccessUtils



DataAccessUtils provides an optionalResult method for Collection as well as Stream arguments.
protected final <T> T findSingle(String query) {
return (T) DataAccessUtils.optionalResult(em.createNamedQuery(query).getResultList());
}​




Multiple TaskSchedulers to be supported with @Scheduled



Now we can have multiple scheduled tasks in our application, with multiple their pool size, thread name and some as daemon. Previously a single application could have only 1 task scheduler. Now we could define multiple schedulers and refer them in the @Scheduled annotation. reference



    @Scheduled(scheduler="${name}",cron = "${scheduler.pay.partner.transaction.cron.expression}", zone = "UTC")


Spring Language Expression(SpEL) enchancement


We can extend SpEL by registering user-defined functions that can be called within the expression string.The function is registered through the EvaluationContext. The following example shows how to register a user-defined function to be invoked via reflection (i.e. a Method).Reference



public abstract class StringUtils {

public static String reverseString(String input) {
StringBuilder backwards = new StringBuilder(input.length());
for (int i = 0; i < input.length(); i++) {
backwards.append(input.charAt(input.length() - 1 - i));
}
return backwards.toString();
}
}

ExpressionParser parser = new SpelExpressionParser();

EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
context.setVariable("reverseString",
StringUtils.class.getDeclaredMethod("reverseString", String.class));

String helloWorldReversed = parser.parseExpression(
"#reverseString('hello')").getValue(context, String.class);


Notable enhancements




Spring Data changes


New CRUD repository interfaces that return List instead of Iterable



Spring Data offers new variants of the CRUD repositories. These return a List for methods that return multiple entities:

- ListCrudRepository

- ListQuerydslPredicateExecutor

- ListQueryByExampleExecutor
They can be used as a drop-in replacement for the interfaces of same name but without the List prefix.

SpEL support in Spring Data JPA @Query definitions


Spring Data JDBC now does support SpEL expressions in @Query annotations and named queries. It works just as for Spring Data JPA .

@InsertOnlyProperty.


You may now annotate properties of the aggregate root with @InsertOnlyProperty. Properties annotated in such way will be written to the database only during insert operations, but they will not be updated afterwards.



reference



@SpringBootTest with Main Methods



The @SpringBootTest annotation can now use the main of any discovered @SpringBootConfiguration class if it’s available. This means that any custom SpringApplication configuration performed by your main method can now be picked up by tests.

To use the main method for a test set the useMainMethod attribute of @SpringBootTest to UseMainMethod.ALWAYS or UseMainMethod.WHEN_AVAILABLE.

Reference



Observability with Spring Boot 3



Spring boot 3 contain numerous autoconfigurations for improved metrics with Micrometer and new distributed tracing support with Micrometer Tracing. A very detailed explanation is provided here



Log4j2 Enhacements







Spring Boot 3 has introduced new Log4j2 extensions that includes the following additional features:

- Profile-specific Configuration

- Environment Properties Lookup

- Log4j2 System Properties
<SpringProfile name=”dev | test”>
<! — configuration to be enabled when the “dev” or “test” profiles are active →
</SpringProfile>

<SpringProfile name=”staging”>
<! — configuration to be enabled when the “staging” profile is active →
</SpringProfile>

<SpringProfile name=”!production”>
<! — configuration to be enabled when the “production” profile is not active →
</SpringProfile>

<Properties> <Property name=”applicationName”>${spring:spring.application.name}</property> </Properties>









Notable enhancements

- Native Images with Spring Boot and GraalVM. [Reference](https://www.baeldung.com/spring-native-intro)

If you want to know about JDK 17 feature please have a loot at my previous blog Java 17 – Best Practices and features.
Please share your thoughts about this blog in the comment section.

Please follow my dhirajjaiswal for future posts.















Labels in this area