Spring Autowiring - It's a kind of magic

This, the second post in the series on the subject of Spring Autowiring, will follow on from part 1 by taking a look into some of the quirks of Autowiring.

My interest in looking into the detail of how Spring performs Autowiring began with a recent piece of development work. The Java code and the Spring configuration for the application I was developing were not aligned, but everything seemed to be working fine.

This post focusses on a simpler, but similar, case where inconsistencies between configuration and code are deliberately introduced to a simple project. It may be expected that inconsistencies would cause application failures, but this is not the case. Spring copes with the errors that are introduced as if by magic.

Autowiring with incomplete configuration

To demonstrate Spring’s behaviour when Autowiring with an incomplete configuration the beans in the example project need to have their own dependencies. A good example is a dependency on Spring’s [ConversionService](https://docs.spring.io/spring/docs/4.3.x/javadoc-api/org/springframework/core/convert/ConversionService.html). The simple project uses the ConversionService as it is easy to code and is fairly common. While the simple implementations of the Converter given below look facile, it should be easy to extrapolate a more complex implementation.

Imagine a music library system that catalogues albums. Each album in the library has an associated artist and is categorised by genre. If the server was a Spring application written in Java it would be useful to have an ArtistService, similar to the AuthorService from part 1.

#pgraham #tech #spring

What is GEEK

Buddha Community

Spring Autowiring - It's a kind of magic
Were  Joyce

Were Joyce

1620720872

Spring vs Spring BooDifference Between Spring and Spring Boot

As an extension of the Spring Framework, Spring Boot is widely used to make development on Spring faster, more efficient and convenient. In this article, we will look at some of the parameters were using Spring Boot can drastically reduce the time and effort required in application development.

What is Spring?

Spring Boot

Difference between Spring and Spring Boot

Advantages of Spring Boot over Spring

Conclusion

#full stack development #spring #spring and spring boot #spring boot

Were  Joyce

Were Joyce

1623559620

Spring Native turns Spring apps into native executables

Spring Native beta release leverages GraalVM to compile Spring Java and Kotlin applications to native images, reducing startup time and memory overhead compared to the JVM.

Spring Native, for compiling Spring Java applications to standalone executables called native images, is now available as a beta release. Native images promise faster startup times and lower runtime memory overhead compared to the JVM.

Launched March 11 and available on start.spring.io, the Spring Native beta compiles Spring applications to native images using the GraalVM multi-language runtime. These standalone executables offer benefits including nearly instant startup (typically fewer than 100ms), instant peak performance, and lower memory consumption, at the cost of longer build times and fewer runtime optimizations than the JVM.

#spring native turns spring apps into native executables #spring native #spring #native executables #spring apps

Were  Joyce

Were Joyce

1623424020

Spring Framework Tutorial

What is the spring framework in Java?

The spring framework is one of the most versatile frameworks in java which is used to bring down the complexity of the development of enterprise-grade applications. The first production release of the spring framework was in March 2004 and since then, this robust and open-source framework has gained tremendous popularity, so much so that it is often referred to by developers all around the world as the “framework of frameworks”. Spring is a loosely coupled, open-source application framework of java. It is lightweight and the inversion of the control container for the Java platform. A large number of Java applications use the core features of the spring framework. In addition to that, extensions have also been developed to allow developers to develop Web Applications on top of the Java Enterprise Edition platform.

#spring #spring-framework #java #spring framework tutorial #why should one learn about the spring framework? #what is the spring framework in java?

Were  Joyce

Were Joyce

1620728340

Spring Framework: To Use Or Not To Use, That Is The Question

It’s impossible to write OOP code with Spring. From its core it promotes the use of singletons and anemic data structures a.k.a. data “objects” a.k.a. DTO. This fuels procedural programming and kills OOP.

In the next paragraphs I’ll highlight three **major **Spring components involved. I start from the core.

IoC Container

The core of Spring is the IoC container, represented by the

ApplicationContextinterface. Basically it defines a context through which we get beans. A bean is an object managed by the container and it has a name attached to it.

We can configure the context thanks to some annotations, called steorotype. These annotations were introduced in Spring 2.5 and enhanced in Spring 3.0. Previously we could only use an external XML. This was even worse…

So we annotate a class with a stereotype, the container reads it and it builds a bean. A bean is a singleton. For this reason it cannot represent anything specific. This means that to do something useful we should pass around data “objects” through them.

A bean is an object only from a technological point of view. But at the conceptual level it’s just a namespace for procedures. In other words it’s a bunch of procedure grouped by a name. Nothing more. Every bean, regardless the stereotype, is bad.

This is not OOP. But I’m not saying anything new. It’s known that singleton are bad. But this (anti)pattern is the Spring backbone.

At this point it should suffice to say that everything else in Spring is based on bean. This means that every Spring application is composed by bean that works on data structure. Definitely this is not OOP.

However I think that things gets worse with the next two components…

#spring #spring-boot #java #spring-mvc #spring-data #oop #procedural-programming #software-engineering

I Dev

1634782355

Spring Boot Exception Handling example

In this tutorial, we're gonna look at an Spring Boot Exception Handling example that uses @ControllerAdvice and @ExceptionHandler.

You can also handle Restful API exception with @RestControllerAdvice, kindly visit:
@RestControllerAdvice example in Spring Boot

This article is originally posted at Bezkoder.

Rest API exception handling

We've created Rest Controller for CRUD Operations and finder method.
Let look at the code:
(step by step to build the Rest APIs is in:

@RestController
public class TutorialController {

  @Autowired
  TutorialRepository tutorialRepository;

  @GetMapping("/tutorials")
  public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {
    try {
      ...
      return new ResponseEntity<>(tutorials, HttpStatus.OK);
    } catch (Exception e) {
      return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @GetMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
    Optional<Tutorial> tutorialData = tutorialRepository.findById(id);

    if (tutorialData.isPresent()) {
      return new ResponseEntity<>(tutorialData.get(), HttpStatus.OK);
    } else {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
  }

  @PutMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
    Optional<Tutorial> tutorialData = tutorialRepository.findById(id);

    if (tutorialData.isPresent()) {
      ...
      return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
    } else {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
  }

  ...

  @DeleteMapping("/tutorials/{id}")
  public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
    try {
      tutorialRepository.deleteById(id);
      return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    } catch (Exception e) {
      return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  @DeleteMapping("/tutorials")
  public ResponseEntity<HttpStatus> deleteAllTutorials() {
    // try and catch
  }

  @GetMapping("/tutorials/published")
  public ResponseEntity<List<Tutorial>> findByPublished() {
    // try and catch
  }
}

You can see that we use try/catch many times for similar exception (INTERNAL_SERVER_ERROR), and there are also many cases that return NOT_FOUND.

Is there any way to keep them simple, any way to attach the error response message smartly and flexibility?
Let's solve the problem now.

Exception Handling with Controller Advice in Spring

Spring supports exception handling by a global Exception Handler (@ExceptionHandler) with Controller Advice (@ControllerAdvice). This enables a mechanism that makes ResponseEntity work with the type safety and flexibility of @ExceptionHandler:
 

@ControllerAdvice
public class ControllerExceptionHandler {

  @ExceptionHandler(value = {ResourceNotFoundException.class, CertainException.class})
  public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
    ErrorMessage message = new ErrorMessage(
        status,
        date,
        ex.getMessage(),
        description);

    return new ResponseEntity<ErrorMessage>(message, HttpStatus.NOT_FOUND);
  }
}

 

The @ControllerAdvice annotation is specialization of @Component annotation so that it is auto-detected via classpath scanning. A Controller Advice is a kind of interceptor that surrounds the logic in our Controllers and allows us to apply some common logic to them.

Its methods (annotated with @ExceptionHandler) are shared globally across multiple @Controller components to capture exceptions and translate them to HTTP responses. The @ExceptionHandler annotation indicates which type of Exception we want to handle. The exception instance and the request will be injected via method arguments.

By using two annotations together, we can:

  • control the body of the response along with status code
  • handle several exceptions in the same method

@ResponseStatus

In the example above, we use @ControllerAdvice for REST web services and return ResponseEntity object additionally.

Spring also provides @ResponseBody annotation which tells a controller that the object returned is automatically serialized into JSON and passed it to the HttpResponse object. This way does not require ResponseEntity but you need to use @ResponseStatus to set the HTTP status code for that exception.
 


@ControllerAdvice
@ResponseBody
public class ControllerExceptionHandler {

  @ExceptionHandler(ResourceNotFoundException.class)
  @ResponseStatus(value = HttpStatus.NOT_FOUND)
  public ErrorMessage resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
    ErrorMessage message = new ErrorMessage(...);
    return message;
  }
}

 

Setup Spring Boot Project

You can follow step by step, or get source code in one of following posts:

The Spring Project contains structure that we only need to add some changes to make the pagination work well.

spring-boot-data-jpa-crud-example-project-structure

Or you can get the new Github source code at the end of this tutorial.

The final project structure will be like this:

spring-boot-exception-handling-example-project-structure

Define Error Response Message

We want to create a our own message response structure instead of using default error response provided by Spring Boot.
Let's define a specific error response structure.

exception/ErrorMessage.java
 

package com.bezkoder.spring.exhandling.exception;

import java.util.Date;

public class ErrorMessage {
  private int statusCode;
  private Date timestamp;
  private String message;
  private String description;

  public ErrorMessage(int statusCode, Date timestamp, String message, String description) {
    this.statusCode = statusCode;
    this.timestamp = timestamp;
    this.message = message;
    this.description = description;
  }

  public int getStatusCode() {
    return statusCode;
  }

  public Date getTimestamp() {
    return timestamp;
  }

  public String getMessage() {
    return message;
  }

  public String getDescription() {
    return description;
  }
}

 

Create Custom Exception

We're gonna throw an exception for Resource not found in Spring Boot controller.
Lets create a ResourceNotFoundException class that extends RuntimeException.

exception/ResourceNotFoundException.java
 

package com.bezkoder.spring.exhandling.exception;

public class ResourceNotFoundException extends RuntimeException {

  private static final long serialVersionUID = 1L;

  public ResourceNotFoundException(String msg) {
    super(msg);
  }
}

 

Create Controller Advice with @ExceptionHandler

Now we're gonna create a special class which is annotated by @ControllerAdvice annotation. This class handles specific exception (ResoureNotFoundException) and global Exception in only one place.

exception/ControllerExceptionHandler.java
 

package com.bezkoder.spring.exhandling.exception;

import java.util.Date;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;

import com.bezkoder.spring.exhandling.exception.ErrorMessage;
import com.bezkoder.spring.exhandling.exception.ResourceNotFoundException;

@ControllerAdvice
public class ControllerExceptionHandler {

  @ExceptionHandler(ResourceNotFoundException.class)
  public ResponseEntity<ErrorMessage> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
    ErrorMessage message = new ErrorMessage(
        HttpStatus.NOT_FOUND.value(),
        new Date(),
        ex.getMessage(),
        request.getDescription(false));

    return new ResponseEntity<ErrorMessage>(message, HttpStatus.NOT_FOUND);
  }

  @ExceptionHandler(Exception.class)
  public ResponseEntity<ErrorMessage> globalExceptionHandler(Exception ex, WebRequest request) {
    ErrorMessage message = new ErrorMessage(
        HttpStatus.INTERNAL_SERVER_ERROR.value(),
        new Date(),
        ex.getMessage(),
        request.getDescription(false));

    return new ResponseEntity<ErrorMessage>(message, HttpStatus.INTERNAL_SERVER_ERROR);
  }
}

 

Modify Controller for using @ControllerAdvice

Our Rest Controller now doesn't have try/catch block, and it will throw ResourceNotFoundException where we want to send NOT_FOUND notification in response message.

controller/TutorialController.java
 

package com.bezkoder.spring.exhandling.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.bezkoder.spring.exhandling.exception.ResourceNotFoundException;
import com.bezkoder.spring.exhandling.model.Tutorial;
import com.bezkoder.spring.exhandling.repository.TutorialRepository;

@CrossOrigin(origins = "http://localhost:8081")
@RestController
@RequestMapping("/api")
public class TutorialController {

  @Autowired
  TutorialRepository tutorialRepository;

  @GetMapping("/tutorials")
  public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {
    List<Tutorial> tutorials = new ArrayList<Tutorial>();

    if (title == null)
      tutorialRepository.findAll().forEach(tutorials::add);
    else
      tutorialRepository.findByTitleContaining(title).forEach(tutorials::add);

    if (tutorials.isEmpty()) {
      return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    return new ResponseEntity<>(tutorials, HttpStatus.OK);
  }

  @GetMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
    Tutorial tutorial = tutorialRepository.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + id));

    return new ResponseEntity<>(tutorial, HttpStatus.OK);
  }

  @PostMapping("/tutorials")
  public ResponseEntity<Tutorial> createTutorial(@RequestBody Tutorial tutorial) {
    Tutorial _tutorial = tutorialRepository.save(new Tutorial(tutorial.getTitle(), tutorial.getDescription(), false));
    return new ResponseEntity<>(_tutorial, HttpStatus.CREATED);
  }

  @PutMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
    Tutorial _tutorial = tutorialRepository.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + id));

    _tutorial.setTitle(tutorial.getTitle());
    _tutorial.setDescription(tutorial.getDescription());
    _tutorial.setPublished(tutorial.isPublished());

    return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
  }

  @DeleteMapping("/tutorials/{id}")
  public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
    tutorialRepository.deleteById(id);

    return new ResponseEntity<>(HttpStatus.NO_CONTENT);
  }

  @DeleteMapping("/tutorials")
  public ResponseEntity<HttpStatus> deleteAllTutorials() {
    tutorialRepository.deleteAll();

    return new ResponseEntity<>(HttpStatus.NO_CONTENT);
  }

  @GetMapping("/tutorials/published")
  public ResponseEntity<List<Tutorial>> findByPublished() {
    List<Tutorial> tutorials = tutorialRepository.findByPublished(true);

    if (tutorials.isEmpty()) {
      return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    return new ResponseEntity<>(tutorials, HttpStatus.OK);
  }

}

 

Run and Test

We finish implementing CRUD REST APIs and exception handling for it.
Run Spring Boot application with command: mvn spring-boot:run.

  • Get a non-existent tutorial:

spring-boot-exception-handling-example-demo-get-404

  • Update a non-existent tutorial:

spring-boot-exception-handling-example-demo-update-404

  • Create tutorial with wrong fields:

spring-boot-exception-handling-example-demo-create-500

  • Delete a non-existent tutorial:

spring-boot-exception-handling-example-demo-delete-500

Conclusion

Today we've built a Exception Handling class for Spring Boot Rest APIs using @ControllerAdvice and @ExceptionHandler. Now you can create your own custom exception handler class or handle global exception in single place at ease.

If you want to add Pagination to this Spring project, you can find the instruction at:
Spring Boot Pagination & Filter example | Spring JPA, Pageable

To sort/order by multiple fields:
Spring Data JPA Sort/Order by multiple Columns | Spring Boot

Or way to write Unit Test for the JPA Repository:
Spring Boot Unit Test for JPA Repositiory with @DataJpaTest

You can also know how to deploy this Spring Boot App on AWS (for free) with this tutorial.
Or Dockerize with Docker Compose: Spring Boot and MySQL example

Happy learning! See you again.

Further Reading

Related Posts:

More Practice:

Source Code

You can find the complete source code for this tutorial on Github.

#spring-framework  #spring #spring-boot #java #web-development