Annotations @Controller and @RestController có ý nghĩa gì? Và sự khác biệt giữa chúng như thế nào? Cùng tìm hiểu cùng Sharecs.net nha.
Annotations @Controller là gì?
@Controller đã được giới thiệu trong bản Spring 2.5 với web controller theo kiến trúc MVC. Tiếp sau đó trong Spring 3.0 đã giới thiệu @ResponseBody để trả lại kiểu trả về của phương thức trực tiếp vào nội dung phản hồi HTTP. Chúng ta có thể kết hợp cả hai @Controller và @ResponseBody để nhanh chóng tạo các dịch vụ web RESTful.
Ví dụ:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping(value="/hello1", method= RequestMethod.GET)
@ResponseBody
String hello1() {
return "Hello World 1";
}
@RequestMapping(value="/hello2", method= RequestMethod.GET)
@ResponseBody
String hello2() {
return "Hello World 2";
}
@RequestMapping(value="/hello3", method= RequestMethod.GET)
@ResponseBody
String hello3() {
return "Hello World 3";
}
}
Trong @Controller có gì ?
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
Mình sẽ giải thích từng annotation một:
- @Target(ElementType.TYPE) : annotation này chỉ áp dụng cho khai báo kiểu ví dụ class, interface, record, không áp dụng cho phương thức.
- @Retention(RetentionPolicy.RUNTIME) : annotation này chỉ có hiệu lực khi ứng dụng chạy, không có hiệu lực khi code, test, hay build ! ( @Retention được sử dụng để chỉ định annotation được sử dụng ở mức độ nào)
- RetentionPolicy.SOURCE : tham chiếu đến mã nguồn, bị loại bỏ trong quá trình biên dịch. Nó sẽ không có sẵn trong lớp được biên dịch.
- RetentionPolicy.CLASS : tham chiếu tới tập tin .class, ó sẵn cho trình biên dịch java nhưng không cho JVM. Nó được bao gồm trong tập tin .class.
- RetentionPolicy.RUNTIME: tham chiếu tới thời gian chạy, sẵn có cho trình biên dịch java và JVM.
- @Documented : đảm bảo chắc chắn rằng annotation này sẽ được liệt kê khi tạo văn bản chú thích mã nguồn.
- @Component : đánh dấu class, interface sẽ trở thành bean component, sẽ được Spring Boot quét (scan) và ghi vào danh sách Application Context. Thông thường các bean component chỉ được khởi tạo 1 lần duy nhất, singleton.
Như vậy các class được annotated bởi @Controller bản chất là một singleton bean component.
Annotations @RestController là gì?
Vì RESTful đang trở nên phổ biến và một class có thể dễ dàng chứa nhiều @ResponseBody phương thức, tạo ra nhiều mã trùng lặp. Vì vậy, Spring 4.0 được giới thiệu @RestController để đơn giản hóa việc tạo các dịch vụ web RESTful.
Xem lại mã nguồn @RestController bản thân nó cũng được chú thích bằng @Controller và @ResponseBody.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(annotation = Controller.class)
String value() default "";
}
Nhìn vào mã nguồn ta thấy @RestController = @Controller + @ResponseBody .
- @RestController sẽ trả dữ liệu về luôn cho trình duyệt, thay vì có thể phải trả dữ liệu cho View Template Engine sau đó View Template Engine kết hợp template + data để sinh ra mã HTML
- @RestController là một @Controller chuyên dùng để tạo REST API. Còn @Controller khai báo bean component để hứng và xử lý request rồi trả về response nói chung.
Lưu ý : @RestController không làm gì khác ngoài hoạt động như một phím tắt cho @Controller và @ResponseBody nó giúp nhà phát triển không phải chú thích @ResponseBody trên tất cả các phương thức xử lý RESTful.
Với @RestController, bây giờ chúng ta có thể viết lại @Controller ví dụ trên như thế này:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping(value="/hello1", method= RequestMethod.GET)
String hello1() {
return "Hello World 1";
}
@RequestMapping(value="/hello2", method= RequestMethod.GET)
String hello2() {
return "Hello World 2";
}
@RequestMapping(value="/hello3", method= RequestMethod.GET)
String hello3() {
return "Hello World 3";
}
}
Lúc này code của chúng ta đã ngắn và đẹp hơn rất nhiều đúng không nào.