Later versions of Spring you can use the @ControllerAdvise annotation for global exception handling (left-side screenshot), it allows you to consolidate the exception handlers in one place, you can also use the @ResponseStatus annotation to set the status code of an HTTP response, in the case of errors we can use BAD_REQUEST (400), NOT_FOUND (404) and many more which gives the client an idea on what went wrong. In the controller advise class we can use the @ExceptionHandler annotation to point to the exception handler class (right-side screenshot), I keep the exception handlers in there own directory called exceptions.
![]() |
![]() |
If you noticed above I use the ModelAndView object to return both data and the view, I use the setViewName() method to point to the 404error.html file in the thymeleaf templates directory and use the addObject() method to attach the exception object, in the thymeleaf template I can use exception object to display messages from the exception using the variable expression ${}, as seen below
So the exception handling is in one file, you can pass back a HTTP status code, plus using the ModelAndView object you can use thymeleaf templates and pass back exception data to the view, and we can do all this with very little code and configuration.
There are time when you want to schedule something to run at a specific time or periodically, the Spring scheduler is robust, easy to use and has a number of options that you can use. First you have to enable scheduling and you simply add the @EnableScheduling annotation to a configuration file.
The @Scheduled annotation offers many ways to schedule a method,
Below are some examples of scheduling tasks, these would be broken into separate files but for demostration purposes I have put them into one file, in a microservices world you will need to setup something (database table) to make sure multiple instances don't run multiple times. There are a few terms that you need to know
Aspect Oriented Programming (AOP) and Interceptors
In this section I am going to show you two ways to run code without changing existing code, Aspect Oriented Programming (AOP) and Interceptors. Both are used for what is known as seperation of cross-cutting concerns, for example you like to run some code before the method is called or after the method is called or during an exception in side the method (AOP), you would like to run some code on a specific URL (Interceptor).
Aspect Oriented Programming (AOP) allows you to intercept a method call both on the way in and the way out, they call this seperation of cross-cutting concerns, it does this without modifying the existing method code. By default Spring Boot is already configured to use AOP, so no further configuration is needed.
There are a number of types of advice
AOP is not something that you use alot but there are times when you might want to use it, so I will show you some basic examples below.
I create a couple of runtime annotations to use with AOP (left-hand screesnhot), you don't have to do this, then I can use the annotations inside my controller (right-hand screenshot)
![]() |
![]() |
First lets take a look at the aspects, you should see that I have used the @Aspect annotation with the @Configuration annotation which means this will be scanned when Spring starts (spring bean). The @Before annotation (left-hand screenshot) uses a wild card for the index controller and the (..) means any data type, so at the bottom of this page you will see the output and this gets called for all methods. The @Around method (left-hand screenshot) uses the @annotation to tie my custom annotation in plus uses a target of controller (@Controller), so as long as the class is a Controller and the method uses the @AopAnno annotation this will get executed. The right-hand screenshot uses the @PointCut annotation and will execute on either the services or doa layers. Notice also that we can incorporate thymeleaf templates using the standard return statement.
![]() |
![]() |
The thymeleaf templates are the normal templates we have already looked at in the Thymeleaf section.
![]() |
![]() |
Spring Boot also offers interceptors, implement the HandlerInterceptor interface, then you can override various methods which are called at specific times, preHandle, postHandle and afterCompletion, these intercept the HTTP request to the controller, see below on how to configure them .
![]() |
![]() |
To configure the interceptors you add some configuration as per below, this time you can use a URL path to trigger the interceptor.
The output from both AOP or using interceptors is as per below
/nmw | ![]() |
/mw | ![]() |
/mwa | ![]() |