Overview Spring Annotations

Customers are regularly asking me if there is some overview over the most important Spring annotations. Until now I always refused to create such an overview, too simplified it would be, I thought.

Finally, I did it and I thought, maybe it be might be useful for beginners using Spring framework and related APIs.

Hope it helps anybody. If, please share using the buttons on the top.

Implicit bean definition using stereotype annotations

@Component
public class MyComponent {
    
// Spring Bean with arbitrary role in application
}

 

@Service
public class MyService {
    
// Spring bean that acts as a service
    // i.e. implements business logic
}

 

@RestController
@RequestMapping
(„/api/myrestcontroller“)
public class MyRestController {
    
//spring bean that acts as a rest controller with base url „/api/myrestcontroller
}

 

@Repository
public class MyRepository {
    
// Spring bean which acts as a repository
    // all database (jdbcjpa, …) exceptions are mapped to subclasses of DataAccessException
}

Spring configuration classes

@Configuration  // denotes the class as a configuration class
// Configuration classes are called only by the spring container
// never by the programmers code
public class MyConfig {
    
//configuration classes define 1 to n Spring Beans
    
@Bean(„albert“// Name of the bean
    
public String nameOfGenius(){
        
return „Albert Einstein“;
    }

    
@Bean //name defaults to method name
    
public LocalDate birthDateOfGenius(){
        
return LocalDate.of(187914);
    }

    
@Bean // Parameter injection example
    
public HumanBeing albertEinstein(@Value(„#{albert}“)String name,
                                     
@Value(„#{birthDateOfGenius}“)LocalDate birthDate){
        
return new HumanBeing(name, birthDate);
    }
}

Annotations for dependency injection

public class InjectionsUsingAutowired {
    
@Autowired // field dependency injection by type
    
private StudentRepo studentRepo;
    
private MyService myService;
    
private TrainingRepo trainingRepo;

    
@Autowired // constructor dependency injection by type
    
public InjectionsUsingAutowired(MyService myService) {
        
this.myService myService;
    }

    
@Autowired // setter dependency Injection by type
    
public void setTrainingRepo(TrainingRepo trainingRepo) {
        
this.trainingRepo trainingRepo;
    }
}

 

public class InjectionsUsingValue {
    
@Value(„#{studentRepo}“// field dependency injection by bean name
    
private StudentRepo studentRepo;
    
private MyService myService;
    
private TrainingRepo trainingRepo;

    
@Autowired // constructor dependency injection by bean name
    
public InjectionsUsingValue(@Value(„#{myServiceImpl1}“MyService myService) {
        
this.myService myService;
    }

    
@Autowired // setter dependency Injection by bean name
    
public void setTrainingRepo(@Value(„#{trainingRepo}“TrainingRepo trainingRepo) {
        
this.trainingRepo trainingRepo;
    }
}

 

 

RestController annotations

@RestController
@RequestMapping(/api/customers)
public class CustomerRestController {
    
@Autowired
    
private CustomerRepo customerRepo;

//GET http://localhost:8080/api/customers
    
@GetMapping
    
public List<CustomerfindAllCustomers(){
        
return customerRepo.findAll();
    }

// GET http://localhost:8080/api/customers/search?name=Michael
    
@GetMapping(search)
    
public List<CustomerfindCustomerByName(@RequestParam(name)String name){
        
return customerRepo.findByName(name);
    }


//GET http://localhost:8080/api/customers/12
    
@GetMapping({id})
    
public ResponseEntity<CustomerfindById(@PathVariable(idLong id){
        
return ResponseEntity.of(customerRepo.findById(id));
    }

//DELETE http://localhost:8080/api/customers/12
    @DeleteMapping({id})
    
@PreAuthorize(„hasAnyRole(‚ADMIN‘)“)
    
public boolean deleteById(@PathVariable(id)Long id){
        
return customerRepo.delete(id);
    }
}

 

/*

POST localhost:8080/api/customers
Content-Type: application/json

{
  „name“: „Katarina“,
  „email“: „katarina@javatraining.at“
}

*/
    
@PostMapping
    
public Customer save(@RequestBody Customer customer){
        
return customerRepo.save(customer);
    }
}

 

@RestController
@RequestMapping
(„/api/customers“)
public class CustomerController {
    
@Autowired
    
private CustomerRepo customerRepo;

    
@GetMapping(„{id}“)
    
public ResponseEntity findById(@PathVariable(„id“Long id){
        
Optional<CustomercustomerOpt customerRepo.findById(id);
        
if (customerOpt.isPresent()){
            
return ResponseEntity.ok().body(customerOpt.get());
        
else {
            
Error error new Error(„Could not find customer“„id=“ + id);
            
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
        }
    }
}

 

 

REST Exception Handlers

@ControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {

    
@ExceptionHandler({DataAccessException.class})
    
public ResponseEntity<ErrorhandleJpaException(DataAccessException ex, WebRequest request){
        
//returning your own error object
        
Error error new Error(„Database operation not sucessful.“ex.getMessage());
        
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }

    
@ExceptionHandler(NullPointerException.class)
    
public ResponseEntity<ObjecthandleNullpointerException(NullPointerException ex, WebRequest request){
        
//convenience method inherited from ResponseEntityExceptionHandler
        
return handleExceptionInternal(ex,
                
„Sorry, something went wrong.“,
                
new HttpHeaders(),HttpStatus.INTERNAL_SERVER_ERROR,
                request);
    }
}

Scope Annotations

@Component
@Scope
(„singleton“)
/**
 * Singleton Scope is the default scope for Spring beans.
 * There is only one instance of this bean. It is created when application starts and lives until application terminates
 */
public class ScopedBean {
    
//…
}

@Component
@Scope
(„prototype“)
/**
 everytime this bean is injected somewhere else
 * a new instance will be created.
 * It will live as long as the bean it is injected into.
 
*/
public class ScopedBean {
    
//…
}

 

@Component
@RequestScope
// alternatively @Scope(„request“)
/**
 * for each user-session in the browser
 * there will be one instance of this bean
 */
public class ScopedBean {
    
//…
}

@Component
@SessionScope
// alternatively @Scope(„session“)
/**
 * for each user-session in the browser
 * there will be one instance of this bean
 */
public class ScopedBean {
    
//…
}

 

JPA & Lombok Annotations

@Data // tell lombok to generate getters, setters, equals, hashCodetoString
@NoArgsConstructor //tell lombok to generate a noargs constructor
@RequiredArgsConstructor //tell lombok to generate a constructor for all NonNull fields
@Entity // required on every entity
@Table(name=„students“// tell JPA to which table this entity should be stored
public class Student {
    
@Id  // tell JPA that
    // this is the primary key of the entity
    
@GeneratedValue(strategy = GenerationType.IDENTITY// tell JPA that DB generates this value
    
@Column(name=„id“// tell JPA in which column this field should be stored
    
private Long id;
    
@NonNull // tell lombok that this field will not be null / may not be null
    
@Column(name=„name“)
    
private String name;
    
@NonNull
    @Column
(name=„email“)
    
private String email;
}

 

 

@Data
@NoArgsConstructor
@RequiredArgsConstructor
@Entity
@Table
(name=„trainings“)
public class Training {
    
@Id
    @GeneratedValue
(strategy = GenerationType.IDENTITY)
    
@Column(name=„id“)
    
private Long id;
    

    
@EqualsAndHashCode.Exclude // tell lombok that this field should not be used for equals and hashCode
    
@ManyToOne(cascade = {CascadeType.MERGECascadeType.PERSIST}) // tell JPA about a foreign key (1:n) relationship to entity trainer
    
@JoinColumn(name=„id_trainer“// name of the column in which the foreign key should be stored
    
private Trainer trainer;

    
@EqualsAndHashCode.Exclude
    @ManyToMany
(cascade = {CascadeType.MERGECascadeType.PERSIST}) // tell JPA about a foreign key (n:m) relationship to entity Student
    
@JoinTable(name = trainings_to_students// tell JPA in which mapping table the foreign key relationship is mapped
            
joinColumns = @JoinColumn(name=„id_training“), // what is the column that relates to my own key
            
inverseJoinColumns = @JoinColumn(name=„id_student“)) // what is the column that relates to the key of entity student
    
private List students new ArrayList<>();
}

 

 

Spring Data Annotations

// definition of a Spring Data JPA repository
public interface TrainingRepo extends JpaRepositoryTrainingRepoCustom {
    
@Query(„select t from Training t left join fetch t.trainer// defining a query using the @Query annotation
    
public List findAllUsingFetchJoinTrainer();

    
@EntityGraph(attributePaths = {trainer“,„students}) // declaring an entityGraph that should be used along with this query
    
@Query(„select t from Training t“)
    
public List findAllUsingEntityGraph();

    
public List findTrainingByTitleLike(String title); // define a query using method name syntax

    
@Query(„select t from Training t where t.trainer.name = :trainername// using parameters in queries
    
public List findTrainingByTrainerName(@Param(„trainername“) String trainername);

     // directly query into a Data Transfer Object
    
@Query(„select new at.javatraining.jpa.entities.dtos.TrainingSummaryDto(t.id, t.titlet.begint.students.size) from Training t“)
    
public List<TrainingSummaryDtogetTrainingSummaries();

}

 

public interface TrainingTitleSummaryView {
    
public Long getId();
    
public String getTitle();
    
@Value(„#{target.students.size()}“)
    
public int getNumberOfStudents();
}

 

// definition of a Spring Data JPA repository
public interface TrainingRepo extends JpaRepositoryLong>, TrainingRepoCustom {
     

     // query into a Spring projection
    
@Query(„select t from Training t“)
    
public List<TrainingTitleSummaryViewgetTrainingTitleSummaryView();
}

 

 

AOP Annotations

@Aspect // define an aspect
@Component // make it a spring component
@Slf4j // generate variable with SLF4J Logger
public class LoggingAspect {

@Around(„execution(* at.javatraining.trainings.service.*.*(..))“)  // define where the aspect should be called
    
public Object log(ProceedingJoinPoint pjpthrows Throwable{
        String methodName = pjp.getSignature().getName();
        String params = Arrays.toString(pjp.getArgs());
        
log.info(„Method call: {} params: {}“methodName, params);
        Object result = pjp.proceed();
        
log.info(„Returning call: {} params: {}“methodName, params);
        
return result;
    }
}

Issue Tracker

Issue Tracker: Unverzichtbare Werkzeuge für effizientes Projektmanagement In der dynamischen Welt der Softwareentwicklung sind Issue Tracker von zentraler Bedeutung für das effektive Management von Fehlern,

Weiterlesen »

Web Services

Web Services: Grundpfeiler moderner Online-Anwendungen Web Services sind eine fundamentale Komponente in der heutigen vernetzten Welt, ermöglichen sie doch die Kommunikation und den Datenaustausch zwischen

Weiterlesen »

Embedded Systems (Eingebettete Systeme)

Embedded Systems: Intelligente Technologie im Herzen moderner Geräte Embedded Systems, also eingebettete Systeme, sind ein integraler Bestandteil zahlreicher moderner Technologien und Geräte. Sie kombinieren Hardware

Weiterlesen »

Single Page Applications

Single Page Applications (SPAs): Die Zukunft der Webentwicklung Single Page Applications (SPAs) haben die Entwicklung moderner Webanwendungen revolutioniert. Sie bieten eine nahtlosere und interaktivere Nutzererfahrung

Weiterlesen »