1. Comparison between @Controller and @RestController
Contrast dimensions | @Controller | @RestController |
---|---|---|
definition | Spring MVC's basic controller annotations |
@Controller + @ResponseBody Combination notes |
Return value processing | Return the view name (need to be with the view resolver) | Directly return JSON/XML data (automatically added@ResponseBody ) |
Applicable scenarios | Traditional MVC architecture (such as JSP/Thymeleaf page rendering) | RESTful API development (front and backend separation scenario) |
HTTP response header |
Content-Type: text/html (default) |
Content-Type: application/json (default) |
Code Example | ```java | ```java |
@Controller | @RestController | |
public class WebCtrl { | public class ApiCtrl { | |
@GetMapping(“/page”) | @GetMapping(“/data”) | |
public String page() { | public User data() { | |
return “index”; // Return to view name | return (); // Automatically convert to JSON | |
} | } | |
} | } |
2. Comparison between using @Data and not using @Data
Contrast dimensions | Using @Data | Not using @Data |
---|---|---|
Code quantity | Automatically generate the following methods: - Getter/setter for all fields - toString() - equals() /hashCode()
|
All methods need to be written manually |
Maintenance | No need to modify the method when increasing or decreasing fields | Field changes require synchronous modification of related methods |
Inheritance relationship processing | Need to be explicitly added@EqualsAndHashCode(callSuper=true) Contains parent class field |
When writing manually, you can directly control whether the parent class field is included |
Framework compatibility | Rely on Lombok plug-in (requires IDE support) | No extra dependencies |
Code Example | ```java | ```java |
@Data | public class User { | |
public class User { | private Long id; | |
private Long id; | private String name; | |
private String name; | ||
// Automatically generate all methods | // Manually write getter/setter | |
} | public Long getId() { return id; } | |
public void setId(Long id) { = id; } | ||
// …Other methods | ||
} |
Things to note:
- use
@Data
When , if the class has an inheritance relationship, you need to add@EqualsAndHashCode(callSuper=true)
- Some scenarios (such as JPA entity classes) need to explicitly define the parameterless constructor (by
@NoArgsConstructor
)
3. Comparison between using @TableName and not using @TableName
Contrast dimensions | Use @TableName | Not using @TableName |
---|---|---|
Table name mapping rules | Explicitly specify the database table name (such as@TableName("sys_user") ) |
By default rule mapping by MyBatis-Plus: Class name camel turns underline (such as SysUser → sys_user ) |
Applicable scenarios | 1. The table name contains special characters (such asuser-info )2. There is no correspondence between class names and table names |
Class names and table names strictly follow the rules of camel to underscore |
Global configuration coverage | Priority is higher than global configuration | Table name prefix can be set uniformly through configuration files:-prefix=sys_
|
Code Example | ```java | ```java |
@Data | @Data | |
@TableName("sys_user") // Explicitly specify the table name | public class SysUser { // The default mapping is sys_user | |
public class User { | private Long id; | |
private Long id; | } | |
} |
Things to note:
- The table name contains SQL keywords and needs to be escaped:
@TableName("
order")
- The table sub-table scenario can be accessed through the dynamic table name processor (
TableNameHandler
)accomplish
4. Comparison of dependency injection annotation
Annotation correct | Core difference | Use scenarios |
---|---|---|
@Autowired vs @Resource | - @Autowired (Spring) Inject by type- @Resource (JSR-250) Inject by name |
Use when specifying the Bean name explicitly@Resource , priority is used when using constructor injection@Autowired
|
@Primary vs @Qualifier | - @Primary Tag the preferred bean- @Qualifier Specify the specific bean name |
When there are multiple beans of the same type, use is preferred.@Primary , when required precise control@Qualifier
|
Code Example:
// @Autowired + @Qualifier @Autowired @Qualifier("mysqlDataSource") private DataSource dataSource; // @Resource @Resource(name = "oracleDataSource") private DataSource dataSource;
5. Comparison of Spring MVC parameter binding annotations
Annotation correct | Core difference | Use scenarios |
---|---|---|
@RequestParam vs @PathVariable | - @RequestParam Get URL parameters- @PathVariable Get URI template variables |
RESTful style URL@PathVariable , traditional form parameters@RequestParam
|
@ModelAttribute vs @RequestBody | - @ModelAttribute Bind Form Data- @RequestBody Bind the JSON request body |
For form submission@ModelAttribute , API interface to transmit complex objects@RequestBody
|
Code Example:
// PathVariable @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { ... } // RequestBody @PostMapping("/users") public ResponseEntity<?> createUser(@RequestBody UserDTO userDTO) { ... }
6. Comparison of JPA/Hibernate mapping annotation
Annotation correct | Core difference | Use scenarios |
---|---|---|
@Entity vs @Table | - @Entity Declare JPA entity class- @Table Specify the database table name |
Used when the class name is inconsistent with the table name@Table
|
@Column vs @Transient | - @Column Mapping database columns- @Transient Tag non-persistent fields |
Used when a field requires a special column name or type@Column , temporarily calculate the field@Transient
|
@OneToMany vs @ManyToOne | - Define one-to-many/many-to-one relationship | Select according to the direction of business relationship (department-employee: for department@OneToMany , employees use@ManyToOne ) |
Code Example:
@Entity @Table(name = "departments") public class Department { @OneToMany(mappedBy = "department") private List<Employee> employees; } @Entity public class Employee { @ManyToOne @JoinColumn(name = "dept_id") private Department department; }
7. Comparison of Spring Boot configuration annotations
Annotation correct | Core difference | Use scenarios |
---|---|---|
@Value vs @ConfigurationProperties | - @Value Inject a single property- @ConfigurationProperties Batch binding properties |
Simple configuration@Value , for complex configuration objects@ConfigurationProperties
|
@Profile vs @Conditional | - @Profile Activate configuration by environment- @Conditional Create a bean by condition |
For multi-environment configuration@Profile , dynamic assembly logic@Conditional
|
Configuration example:
# app: security: enabled: true timeout: 300
Code implementation:
@Configuration @ConfigurationProperties(prefix = "") public class SecurityConfig { private boolean enabled; private int timeout; // getters/setters }
8. Lombok annotation comparison
Annotation correct | Core difference | Use scenarios |
---|---|---|
@Data vs @Value | - @Data Generate mutable objects- @Value Generate immutable objects (final fields) |
Use when you need to modify the field value@Data , read-only data transmission object@Value
|
@Builder vs @AllArgsConstructor | - @Builder Support chain construction- @AllArgsConstructor Generate a full parameter constructor |
For complex object construction@Builder , for the whole ginseng construction@AllArgsConstructor
|
Code Example:
@Value @Builder public class ImmutablePoint { private final int x; private final int y; } // useImmutablePoint point = ().x(10).y(20).build();
9. Comparison of transaction management annotations
Annotation correct | Core difference | Use scenarios |
---|---|---|
@Transactional vs @Modifying | - @Transactional Declare transaction boundaries- @Modifying Tag DML operations |
Service layer method@Transactional , JPA update query@Modifying
|
Code Example:
@Service public class UserService { @Transactional public void updateUser(User user) { (user); } } @Repository public interface UserRepository extends JpaRepository<User, Long> { @Modifying @Query("UPDATE User u SET = ?1 WHERE = ?2") int updateNameById(String name, Long id); }
10. Comparison of test-related annotations
Annotation correct | Core difference | Use scenarios |
---|---|---|
@Mock vs @MockBean | - @Mock (Mockito) Create a mock object- @MockBean (Spring Boot Test) Replace Beans in Spring Container |
For unit testing@Mock , integrated test@MockBean
|
@SpringBootTest vs @WebMvcTest | - @SpringBootTest Load the full context- @WebMvcTest Load only web layer components |
Fully integrated test@SpringBootTest , for control layer isolation test@WebMvcTest
|
Test Example:
// Full integration test@SpringBootTest class UserServiceIntegrationTest { @Autowired private UserService userService; } // Control layer testing@WebMvcTest() class UserControllerTest { @MockBean private UserService userService; @Autowired private MockMvc mockMvc; }
Comprehensive comparison summary table
Functional Scenario | Recommended annotation combination | Typical Applications |
---|---|---|
REST API Development |
@RestController + @RequestBody + @Valid
|
Front- and back-end separation interface development |
JPA Entity Mapping |
@Entity + @Table + @Column + @OneToMany
|
Database table structure mapping |
Configuration Management |
@ConfigurationProperties + @Profile
|
Multi-environment configuration switching |
Test coverage |
@SpringBootTest + @MockBean + @DataJpaTest (Select on demand) |
Hierarchical testing strategy |
Dependency injection | Constructor injection is preferred,@Autowired + @Qualifier
|
Avoid circular dependencies |
Best Practice Recommendations
Layered useStrictly follow the Controller→Service→Repository hierarchical architecture to avoid the use of cross-layer annotations.
-
Minimize annotation
- Preferential use of combined annotations provided by the framework (e.g.
@RestController
replace@Controller
+@ResponseBody
) - Avoid repeated annotations (such as using them at the same time
@Component
and@Service
)
- Preferential use of combined annotations provided by the framework (e.g.
-
Lombok specifications
- Uniform use of entity classes
@Data
+@Builder
- Disable unconstrained
@AllArgsConstructor
- Uniform use of entity classes
-
Transaction control
- Service layer unified statement
@Transactional(readOnly = true)
- Explicitly specified write operations
@Transactional(rollbackFor = )
- Service layer unified statement
-
Test isolation
- Unit testing using Mockito + JUnit5
- Integration Testing on Demand Selection
@WebMvcTest
or@DataJpaTest
Through systematic annotation comparison and combination use, code standardization and team collaboration efficiency can be significantly improved. It is recommended to combine code quality management tools such as SonarLint to ensure the rationality and consistency of the use of annotations.
Summarize
This is the end of this article about comparing Java common annotation extensions. For more related Java common annotation extensions, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!