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 might be useful for beginners using Spring framework and related APIs.

Hope it helps anyone. 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
    // ie 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 (jdbcyep, …) 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 volume 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 Albert Einstein(@Value(“#{albert}”)String name,
                                     
@Value(“#{birthDateOfGenius}”)LocalDate birthDate){
        
return new HumanBeing(Surname, 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 Cunning<CustomerfindAllCustomers(){
        
return customerRepo.findAll();
    }

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


//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(“Couldn’t 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 successful.“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 Nonzero fields.fields
@Entity // required on every entity
@Table(name=“students”// tell JPA to which table this entity should be stored
public class College 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="Surname")
    
private string Surname;
    
@NonNull
    @Column
(name="e-mail")
    
private string e-mail;
}

 

 

@Data
@NoArgsConstructor
@RequiredArgsConstructor
@Entity
@Table
(name=“training”)
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 = training_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 Cunning 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 Cunning findAllUsingFetchJoinTrainer();

    
@EntityGraph(attributePaths = {Trainer",“students}) // declaring on entityGraph that should be used along with this query
    
@Query(“select t from Training t”)
    
public Cunning findAllUsingEntityGraph();

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

    
@Query(“select t from Training t where t.trainer.name = :trainer name// using parameters in queries
    
public Cunning findTrainingByTrainerName(@Param(“coach name”) string trainer name);

     // 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 variables 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;
    }
}