Why we need Custom Exception
Exceptions are technical causes which should be wrapped in a presentable way with a specific business logic and workflow. adding a higher abstraction layer for the exception handling, which results in more meaningful and readable API

How to write Custom Exception
All you need to do is create a new class and have it extend Exception. If you want an Exception that is unchecked, you need to extend RuntimeException.
Note: A checked Exception is one that requires you to either surround the Exception in a try/catch block or have a ‘throws’ clause on the method declaration. (like IOException) Unchecked Exceptions may be thrown just like checked Exceptions, but you aren’t required to explicitly handle them in any way (IndexOutOfBoundsException).

Exception, if you want your exception to be checked (i.e: required in a throws clause).RuntimeException, if you want your exception to be unchecked.

Creating Custom Checked Exception
Note:constructor takes a Throwable’s subclass which is the origin (cause) of the current exception

public class StudentStoreException extends Exception {
     public StudentStoreException(String message, Throwable cause) {
        super(message, cause);
    }
}

Creating Custom Unchecked Exception

public class IncorrectFileExtensionException 
  extends RuntimeException {
    public IncorrectFileExtensionException(String errorMessage, Throwable err) {
        super(errorMessage, err);
    }
}

Methods in Custom Exception

public class MyOwnException extends Exception {
    public MyOwnException() {

    }

    public MyOwnException(String message) {
        super(message);
    }

    public MyOwnException(Throwable cause) {
        super(cause);
    }

    public MyOwnException(String message, Throwable cause) {
        super(message, cause);
    }
}

Minimal Requirment

  1. Java 17 or higher
  2. Jakarta EE 10
  3. Spring Framework 6
  4. Works on Maven 3.5+
  5. Tomcat 10.0
  6. Improved observability with Micrometer and Micrometer Tracing

Improvements
Performance enhancements and optimizations to boost application responsiveness and efficiency.These improvements focus on reducing startup times, minimizing memory footprint, and optimizing resource utilization.

Changes in Code

  1. When we wanted to configure the Security settings, we had to extend the WebSecurityConfigurerAdapter class.This class has been deprecated and removed in Spring Security 6.
    Instead, we should now take a more component-based approach and create a bean of type SecurityFilterChain.

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {
     @Bean
      public SecurityFilterChain configure(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(requests -> requests
                .requestMatchers(new AntPathRequestMatcher("/openapi/openapi.yml")).permitAll()
                .anyRequest().authenticated())
            .httpBasic();
        return http.build();
      }
    }
    
  2. Instead of using authorizeRequests, which has been deprecated, we should now use authorizeHttpRequests.This method is part of the HttpSecurity configuration and allows you to configure fine-grained request matching for access control.
  3. Spring Security 6, AntMatcher, MvcMatcher, and RegexMatcher have been depreciated and replaced by requestMatchers or securityMatchers for path-based access control. This allows us to match requests based on patterns or other criteria without relying on specific matchers.