Close to 8000 words of Spring/SpringBoot common annotation summary! Schedule!

0. Preface

Hello, I'm brother Guide! This is my 221 excellent original articles. If you need to reprint, please indicate the address at the beginning of the article, crab!

This article has been included in my open source Java project JavaGuide of 75K Star: https://github.com/Snailclimb/JavaGuide
It's no exaggeration to say that the Spring/SpringBoot common annotations introduced in this article basically cover most of the common scenarios you encounter in your work. For each annotation, I have said the specific usage, master and understand. There is no big problem in using spring boot to develop projects!

The whole directory is as follows, with a little more contents:

Why write this article?

Recently, I saw that there are many articles about spring boot common annotations reprinted on the Internet. After reading the contents of the articles, I really think that the quality is a little low, and it will mislead people who don't have much practical experience (these people occupy the majority). So, I spent about two days simply summarizing.

Because of my limited ability and energy, if there is anything wrong or need to be improved, please help to point out! Brother Guide, thank you very much!

1. @SpringBootApplication

Here I'll introduce @ SpringBootApplication alone, although we usually don't take the initiative to use it.

Guide: this annotation is the cornerstone of the Spring Boot project. After the Spring Boot project is created, it will be added to the main class by default.

@SpringBootApplication
public class SpringSecurityJwtGuideApplication {
      public static void main(java.lang.String[] args) {
        SpringApplication.run(SpringSecurityJwtGuideApplication.class, args);
    }
}

We can think of @ SpringBootApplication as a collection of @ Configuration, @ EnableAutoConfiguration, @ ComponentScan annotations.

package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
   ......
}

package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

According to the SpringBoot official website, the functions of these three annotations are as follows:

  • @Enable autoconfiguration: enable the autoconfiguration mechanism of SpringBoot
  • @ComponentScan: scan the bean annotated by @ Component (@Service,@Controller). The annotation will scan all classes under the package where the class is located by default.
  • @Configuration: allows additional bean s to be registered or other configuration classes to be imported in the Spring context

2. Spring Bean related

2.1. @Autowired

Automatically import objects into classes. The injected classes are also managed by Spring containers. For example, Service classes are injected into Controller classes.

@Service
public class UserService {
  ......
}

@RestController
@RequestMapping("/users")
public class UserController {
   @Autowired
   private UserService userService;
   ......
}

2.2. Component,@Repository,@Service, @Controller

We usually use @ Autowired annotation to let Spring container help us automatically assemble beans. To identify the class as a class that can be used for @ Autowired annotation auto assembled beans, the following annotation can be used:

  • @Component: a general annotation that can mark any class as a Spring component. If a Bean does not know which layer it belongs to, it can be annotated with @ Component annotation.
  • @Repository: the corresponding persistence layer, namely Dao layer, is mainly used for database related operations.
  • @Service: the corresponding service layer, mainly involving some complex logic, needs to use the Dao layer.
  • @Controller: corresponding to the Spring MVC control layer, the main user accepts the user request and calls the Service layer to return the data to the front-end page.

2.3. @RestController

@The RestController annotation is a collection of @ Controller and @ ResponseBody, indicating that this is a Controller bean, and the return value of the function is directly filled into the HTTP response body, which is a REST style Controller.

Guide brother: now it's all front and back end separation. To be honest, I haven't used @ Controller for a long time. If your project is too old, think I didn't say it.

If @ controller alone is used without @ ResponseBody, it is generally used when a view is to be returned. This is a more traditional Spring MVC application, which corresponds to the situation where the front and back ends are not separated. @Controller +@ResponseBody returns JSON or XML data

For a comparison between @ RestController and @ Controller, see this article: @RestController vs @Controller.

2.4. @Scope

Declare the scope of Spring Bean using the following methods:

@Bean
@Scope("singleton")
public Person personSingleton() {
    return new Person();
}

There are four common scopes of Spring Bean:

  • Singleton: the only bean instance. By default, all beans in Spring are singleton.
  • prototype: each request creates a new bean instance.
  • Request: each HTTP request will generate a new bean, which is only valid in the current HTTP request.
  • Session: each HTTP request will generate a new bean, which is only valid in the current HTTP session.

2.5. Configuration

It is generally used to declare Configuration classes, and can be replaced by @ Component annotation, but it is more semantic to use Configuration annotation to declare Configuration classes.

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }

}

3. Handle common HTTP request types

Five common request types:

  • GET: requests to GET a specific resource from the server. For example: GET /users
  • POST: create a new resource on the server. For example: POST /users (create students)
  • PUT: update the resources on the server (the client provides the whole updated resources). For example: PUT /users/12 (update student number 12)
  • DELETE: deletes a specific resource from the server. For example: DELETE /users/12
  • PATCH: update the resources on the server (the client provides the changed attributes, which can be seen as part of the update). The usage is relatively small. Here is no example.

3.1. GET request

@GetMapping("users") is equivalent to @ RequestMapping(value="/users",method=RequestMethod.GET)

@GetMapping("/users")
public ResponseEntity<List<User>> getAllUsers() {
 return userRepository.findAll();
}

3.2. POST request

@PostMapping("users") is equivalent to @ RequestMapping(value="/users",method=RequestMethod.POST)

About the use of @ RequestBody annotation, we will talk about it in the "pass value before and after" section below.

@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest userCreateRequest) {
 return userRespository.save(user);
}

3.3. PUT request

@PutMapping("/users/{userId}") is equivalent to @ RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)

@PutMapping("/users/{userId}")
public ResponseEntity<User> updateUser(@PathVariable(value = "userId") Long userId,
  @Valid @RequestBody UserUpdateRequest userUpdateRequest) {
  ......
}

3.4. DELETE request

@DeleteMapping("/users/{userId}") is equivalent to @ RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)

@DeleteMapping("/users/{userId}")
public ResponseEntity deleteUser(@PathVariable(value = "userId") Long userId){
  ......
}

3.5. PATCH request

In general, in actual projects, we use PATCH request to update data only when PUT is not enough.

  @PatchMapping("/profile")
  public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) {
        studentRepository.updateDetail(studentUpdateRequest);
        return ResponseEntity.ok().build();
    }

4. Front and rear end transmission value

Mastering the correct posture of front and back end transmission is the first step for you to start CRUD!

4.1. @PathVariable and @ RequestParam

@PathVariable is used to get the path parameter, @ RequestParam is used to get the query parameter.

Take a simple example:

@GetMapping("/klasses/{klassId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
         @PathVariable("klassId") Long klassId,
         @RequestParam(value = "type", required = false) String type ) {
...
}

If the url we requested is: / klasses/{123456}/teachers?type=web

Then the data obtained by our service is: klassId=123456,type=web.

4.2. @RequestBody

It is used to read the body part of the Request (maybe POST,PUT,DELETE,GET Request) and the data with the content type of application/json format. After receiving the data, it will automatically bind the data to the Java object. The system will use HttpMessageConverter or custom HttpMessageConverter to convert json strings in the requested body into Java objects.

I use a simple example to demonstrate the basic use!

We have a registered interface:

@PostMapping("/sign-up")
public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) {
  userService.save(userRegisterRequest);
  return ResponseEntity.ok().build();
}

UserRegisterRequest object:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRegisterRequest {
    @NotBlank
    private String userName;
    @NotBlank
    private String password;
    @FullName
    @NotBlank
    private String fullName;
}

We send a post request to this interface, and the body carries JSON data:

{"userName":"coder","fullName":"shuangkou","password":"123456"}

In this way, our backend can directly map the json format data to our UserRegisterRequest class.

A kind of Note: a request method can only have one @ RequestBody, but it can have multiple @ RequestParam and @ PathVariable. If your method has to use two @ requestbodies to accept data, maybe your database design or system design is out of order!

5. Read configuration information

In many cases, we need to put some common configuration information, such as Alibaba cloud oss, SMS, wechat authentication and so on, into the configuration file.

Let's take a look at how Spring can help us read the configuration information from the configuration file.

Our data source application.yml is as follows:

wuhan2020: 2020 A novel coronavirus outbreak in Wuhan in early 2008 was a serious epidemic. However, I believe everything will be over. Come on, Wuhan! Go China!

my-profile:
  name: Guide Brother
  email: koushuangbwcx@163.com

library:
  location: Hubei, Wuhan, China
  books:
    - name: Basic law of genius
      description: Lin Chaoxi, 22, learned that Pei Zhi, the campus God who had been secretly in love for many years, was about to go abroad for further education on the day when her father diagnosed Alzheimer's disease. The school that the other side admitted was the one that her father gave up for her.
    - name: The order of time
      description: Why do we remember the past, not the future? What does time "pass" mean? Are we in time, or is time in us? CarolĀ·Using poetic words, Rowe invites us to think about the essence of time, an ancient problem.
    - name: Great me
      description: How to form a new habit? How to make the mind more mature? How to have a high quality relationship? How to get out of the difficult time of life?

5.1 @ value (common)

Use @ Value("${property}") to read simpler configuration information:

@Value("${wuhan2020}")
String wuhan2020;

5.2 @ configurationproperties (common)

Read the configuration information through @ ConfigurationProperties and bind to the bean.

@Component
@ConfigurationProperties(prefix = "library")
class LibraryProperties {
    @NotEmpty
    private String location;
    private List<Book> books;

    @Setter
    @Getter
    @ToString
    static class Book {
        String name;
        String description;
    }
  //Omit getter/setter
  ......
}

You can inject it into a class just as you would with a normal Spring bean.

5.3. PropertySource (not commonly used)

@PropertySource reads the specified properties file

@Component
@PropertySource("classpath:website.properties")

class WebSite {
    @Value("${url}")
    private String url;

  //Omit getter/setter
  ......
}

For more information, see this article:< How to read the configuration file gracefully in 10 minutes?> .

6. Parameter verification

The importance of data verification is needless to say. Even in the case of front-end data verification, we still need to verify the data passed into the back-end again to avoid users bypassing the browser and directly requesting some illegal data from the back-end through some HTTP tools.

JSR(Java Specification Requests) is a set of JavaBean parameter verification standards. It defines many commonly used verification annotations. We can directly add these annotations to the properties of our JavaBean, so that we can verify when we need to verify, which is very convenient!

During the verification, we actually use the Hibernate Validator framework. Hibernate Validator is the original data validation framework of Hibernate team, Hibernate Validator 4.x is the reference implementation of Bean Validation 1.0 (JSR 303), Hibernate Validator 5.x is the reference implementation of Bean Validation 1.1 (JSR 349), and the latest version of Hibernate Validator 6.x is the reference implementation of Bean Validation 2.0 (JSR 380).

The hibernate validator package already exists in the spring boot starter web dependency of the spring boot project, so there is no need to reference the dependency. As shown in the following figure (generated through the idea plug-in Maven Helper):

Non spring boot projects need to introduce their own dependent packages. I will not explain them here. For details, please refer to my article:< How to do parameter verification in Spring/Spring Boot? All you need to know is here!>.

A kind of Note: for all annotations, it is recommended to use JSR annotation, namely javax.validation.constraints instead of org.hibernate.validator.constraints

6.1. Notes on some common field validation

  • @NotEmpty of the commented string cannot be null or empty
  • @NotBlank the commented string is not null and must contain a non blank character
  • @Null the annotated element must be null
  • @NotNull the annotated element must not be null
  • @AssertTrue the annotated element must be true
  • @AssertFalse the annotated element must be false
  • @Pattern(regex=,flag =) the annotated element must conform to the specified regular expression
  • @The element to which Email is annotated must be in Email format.
  • @Min(value) the annotated element must be a number whose value must be greater than or equal to the specified minimum value
  • @Max(value) the annotated element must be a number whose value must be less than or equal to the specified maximum value
  • @DecimalMin(value) the annotated element must be a number whose value must be greater than or equal to the specified minimum value
  • @DecimalMax(value) the annotated element must be a number whose value must be less than or equal to the specified maximum value
  • @Size(max=, min =) the size of the annotated element must be within the specified range
  • @The annotated element of Digits (integer, fraction) must be a number, and its value must be within the acceptable range
  • @The element that paste is annotated must be a date in the Past
  • @Future annotated element must be a future date
  • ......

6.2. Request body

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    @NotNull(message = "classId Cannot be empty")
    private String classId;

    @Size(max = 33)
    @NotNull(message = "name Cannot be empty")
    private String name;

    @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex Value not in optional range")
    @NotNull(message = "sex Cannot be empty")
    private String sex;

    @Email(message = "email Incorrect format")
    @NotNull(message = "email Cannot be empty")
    private String email;

}

We added @ Valid annotation to the parameters to be verified. If the verification fails, it will throw MethodArgumentNotValidException.

@RestController
@RequestMapping("/api")
public class PersonController {

    @PostMapping("/person")
    public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) {
        return ResponseEntity.ok().body(person);
    }
}

6.3. Verify request parameters (Path Variables and Request Parameters)

Be sure not to forget to add the Validated annotation to the class. This parameter can tell Spring to verify the method parameters.

@RestController
@RequestMapping("/api")
@Validated
public class PersonController {

    @GetMapping("/person/{id}")
    public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "Exceed id The scope of") Integer id) {
        return ResponseEntity.ok().body(id);
    }
}

For more information on how to verify parameters in Spring projects, see< How to do parameter verification in Spring/Spring Boot? All you need to know is here! >This article.

7. Global handling of Controller layer exceptions

Introduce the global handling of Controller layer exceptions necessary for our Spring project.

Related notes:

  1. @ControllerAdvice: annotation defines global exception handling class
  2. @ExceptionHandler: annotation declaration exception handling method

How to use it? Take our parameter verification in Section 5 for example. If the method parameter is wrong, MethodArgumentNotValidException will be thrown. Let's handle this exception.

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * Request parameter exception handling
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
       ......
    }
}

For more information on Spring Boot exception handling, please refer to my two articles:

  1. Several common postures of spring boot handling exceptions
  2. Simply encapsulate an elegant Spring Boot global exception handling with enumeration!

8. JPA related

8.1. Create table

@Entity declares that a class corresponds to a database entity.

@Table settings indicate

@Entity
@Table(name = "role")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String description;
    //Omit getter/setter
}

8.2. Create primary key

@Id: declare a field as the primary key.

After using @ Id declaration, we also need to define the primary key generation policy. We can use @ GeneratedValue to specify the primary key generation policy.

1. Use @ GeneratedValue directly to specify the primary key generation policy by using the four primary key generation policies provided by JPA.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

JPA uses enumeration to define the common primary key generation strategies in 4, as follows:

Guige: a use of enumerating substitution constants

public enum GenerationType {

    /**
     * Use a specific database table to save the primary key
     * The persistence engine generates the primary key through a specific table in the relational database,
     */
    TABLE,

    /**
     *In some databases, primary key self growth is not supported. For example, Oracle and PostgreSQL provide a mechanism called "sequence" to generate primary key
     */
    SEQUENCE,

    /**
     * Primary key self growth
     */
    IDENTITY,

    /**
     *Give the primary key generation strategy to the persistence engine,
     *The persistence engine will choose one of the above three primary key generation strategies based on the database
     */
    AUTO
}

@The default policy used by the generated value annotation is GenerationType.AUTO

public @interface GeneratedValue {

    GenerationType strategy() default AUTO;
    String generator() default "";
}

Generally speaking, when using MySQL database, the GenerationType.IDENTITY strategy is more common (for distributed system, distributed ID needs to be considered additionally).

2. Declare a primary key policy through @ GenericGenerator, and then @ GeneratedValue uses this policy

@Id
@GeneratedValue(generator = "IdentityIdGenerator")
@GenericGenerator(name = "IdentityIdGenerator", strategy = "identity")
private Long id;

Equivalent to:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

The primary key generation strategies provided by jpa are as follows:

public class DefaultIdentifierGeneratorFactory
        implements MutableIdentifierGeneratorFactory, Serializable, ServiceRegistryAwareService {

    @SuppressWarnings("deprecation")
    public DefaultIdentifierGeneratorFactory() {
        register( "uuid2", UUIDGenerator.class );
        register( "guid", GUIDGenerator.class );            // can be done with UUIDGenerator + strategy
        register( "uuid", UUIDHexGenerator.class );            // "deprecated" for new use
        register( "uuid.hex", UUIDHexGenerator.class );     // uuid.hex is deprecated
        register( "assigned", Assigned.class );
        register( "identity", IdentityGenerator.class );
        register( "select", SelectGenerator.class );
        register( "sequence", SequenceStyleGenerator.class );
        register( "seqhilo", SequenceHiLoGenerator.class );
        register( "increment", IncrementGenerator.class );
        register( "foreign", ForeignGenerator.class );
        register( "sequence-identity", SequenceIdentityGenerator.class );
        register( "enhanced-sequence", SequenceStyleGenerator.class );
        register( "enhanced-table", TableGenerator.class );
    }

    public void register(String strategy, Class generatorClass) {
        LOG.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() );
        final Class previous = generatorStrategyToClassNameMap.put( strategy, generatorClass );
        if ( previous != null ) {
            LOG.debugf( "    - overriding [%s]", previous.getName() );
        }
    }

}

8.3. Set field type

@Column declares the field.

Example:

Set the database field name corresponding to the property userName as user ļ¹£ name, with a length of 32, non empty

@Column(name = "user_name", nullable = false, length=32)
private String userName;

It is quite common to set the field type and add the default value.

Column(columnDefinition = "tinyint(1) default 1")
private Boolean enabled;

8.4. Specify not to persist specific fields

@Transient: declare the fields that do not need to be mapped with the database, and do not need to be saved into the database when saving.

If we want the secrect field not to be persisted, we can declare it with the @ Transient keyword.

Entity(name="USER")
public class User {

    ......
    @Transient
    private String secrect; // not persistent because of @Transient

}

In addition to the @ Transient keyword declaration, you can also use the following methods:

static String secrect; // not persistent because of static
final String secrect = "Satish"; // not persistent because of final
transient String secrect; // not persistent because of transient

Generally, there are many ways to use annotations.

8.5. Declaration of large fields

@Lob: declare a field as a large field.

@Lob
private String content;

More detailed statement:

@Lob
//Specify the acquisition strategy of Lob type data. Fetchtype.eagle indicates non delayed loading, while FetchType. LAZY indicates delayed loading;
@Basic(fetch = FetchType.EAGER)
//The columnDefinition property specifies the Lob field type corresponding to the data table
@Column(name = "content", columnDefinition = "LONGTEXT NOT NULL")
private String content;

8.6. Create field of enumeration type

You can use fields of enumeration type, but enumeration fields need to be decorated with @ Enumerated annotation.

public enum Gender {
    MALE("Male"),
    FEMALE("Female sex");

    private String value;
    Gender(String str){
        value=str;
    }
}
@Entity
@Table(name = "role")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String description;
    @Enumerated(EnumType.STRING)
    private Gender gender;
    //Omit getter/setter
}

The corresponding storage in the database is MAIL/FEMAIL.

8.7. Add audit function

As long as the class inherits AbstractAuditBase, the following four fields will be added by default.

@Data
@AllArgsConstructor
@NoArgsConstructor
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class AbstractAuditBase {

    @CreatedDate
    @Column(updatable = false)
    @JsonIgnore
    private Instant createdAt;

    @LastModifiedDate
    @JsonIgnore
    private Instant updatedAt;

    @CreatedBy
    @Column(updatable = false)
    @JsonIgnore
    private String createdBy;

    @LastModifiedBy
    @JsonIgnore
    private String updatedBy;
}

The corresponding configuration class of our audit function may be as follows (Spring Security project):


@Configuration
@EnableJpaAuditing
public class AuditSecurityConfiguration {
    @Bean
    AuditorAware<String> auditorAware() {
        return () -> Optional.ofNullable(SecurityContextHolder.getContext())
                .map(SecurityContext::getAuthentication)
                .filter(Authentication::isAuthenticated)
                .map(Authentication::getName);
    }
}

Briefly introduce some notes designed above:

  1. @CreatedDate: indicates that this field is a creation time field. When this entity is insert ed, the value will be set
  2. @CreatedBy: indicates that the field is created by. When the entity is insert ed, the value will be set

@LastModifiedDate, @ LastModifiedBy are the same.

@Enable JPA Auditing: enable JPA auditing.

8.8. Delete / modify data

@The Modifying annotation prompts JPA that this operation is a modification operation. Note that it should be used in conjunction with the @ Transactional annotation.

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

    @Modifying
    @Transactional(rollbackFor = Exception.class)
    void deleteByUserName(String userName);
}

8.9. Relationship

  • @OneToOne declares a one-to-one relationship
  • @OneToMany declares a one to many relationship
  • @ManyToOne declares many to one relationship
  • MangToMang declares many to many relationships

For more articles about Spring Boot JPA, see my article: Understand how to use JPA correctly in Spring Boot .

9. Transaction

Just use @ Transactional annotation on the method to open the transaction!

@Transactional(rollbackFor = Exception.class)
public void save() {
  ......
}

We know that exceptions are divided into runtime exceptions and non runtime exceptions. In the @ Transactional annotation, if the rollbackFor attribute is not configured, things will only roll back when they encounter a RuntimeException. With rollbackFor=Exception.class, things can also roll back when they encounter non runtime exceptions.

@Transactional annotations are generally used to act on classes or methods.

  • For class: when the @ Transactional annotation is placed on the class, it means that all public methods of the class are configured with the same transaction attribute information.
  • Action on method: when the class is configured with @ Transactional and the method is configured with @ Transactional, the transaction of the method will overwrite the transaction configuration information of the class.

For more information about Spring transactions, see:

  1. Probably the most beautiful detailed explanation of Spring transaction management
  2. Say six @ Transactional annotation failure scenarios in one breath

10. json data processing

10.1. Filtering json data

@The JsonIgnoreProperties function is used on classes to filter out specific fields that are not returned or parsed.

//Filter the userRoles property when generating json
@JsonIgnoreProperties({"userRoles"})
public class User {

    private String userName;
    private String fullName;
    private String password;
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}

@JsonIgnore is generally used for the properties of a class. Its function is the same as the above @ jsonignorproperties.


public class User {

    private String userName;
    private String fullName;
    private String password;
   //Filter the userRoles property when generating json
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}

10.2. Format json data

@JsonFormat is generally used to format json data. :

For example:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
private Date date;

10.3. Flattening objects

@Getter
@Setter
@ToString
public class Account {
    @JsonUnwrapped
    private Location location;
    @JsonUnwrapped
    private PersonInfo personInfo;

  @Getter
  @Setter
  @ToString
  public static class Location {
     private String provinceName;
     private String countyName;
  }
  @Getter
  @Setter
  @ToString
  public static class PersonInfo {
    private String userName;
    private String fullName;
  }
}

Before flattening:

{
    "location": {
        "provinceName":"Hubei",
        "countyName":"Wuhan"
    },
    "personInfo": {
        "userName": "coder1234",
        "fullName": "shaungkou"
    }
}

After using the @ JsonUnwrapped flat object:

@Getter
@Setter
@ToString
public class Account {
    @JsonUnwrapped
    private Location location;
    @JsonUnwrapped
    private PersonInfo personInfo;
    ......
}
{
  "provinceName":"Hubei",
  "countyName":"Wuhan",
  "userName": "coder1234",
  "fullName": "shaungkou"
}

11. Test related

@ActiveProfiles are generally used on test classes to declare valid Spring configuration files.

@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Slf4j
public abstract class TestBase {
  ......
}

@Test declares a method as a test method

@The data of the declared test method of Transactional will be rolled back to avoid polluting the test data.

@Provided by WithMockUser Spring Security, it is used to simulate a real user and can be granted permissions.

    @Test
    @Transactional
    @WithMockUser(username = "user-id-18163138155", authorities = "ROLE_TEACHER")
    void should_import_student_success() throws Exception {
        ......
    }

Let's summarize it here for the time being! Although it took a long time to finish writing, some common annotations may still be missed, so I synchronized the article to Github, Github address: https://github.com/Snailclimb/JavaGuide/blob/master/docs/system-design/framework/spring/spring-annotations.md Welcome to perfect!

This article has been included in my open source Java project JavaGuide of 75K Star: https://github.com/Snailclimb/JavaGuide.

Tags: Java Spring Database JSON Hibernate

Posted on Tue, 05 May 2020 08:51:50 -0400 by alanrenouf