Dưới đây là tổng hợp những câu hỏi phỏng vấn Spring cho đối tượng Fresher.
Trong Spring, Inversion of Control (IoC) và Dependency Injection (DI) là 2 khái niệm có mối quan hệ chặt chẽ với nhau.
IoC là một nguyên lý thiết kế phần mềm (design principle), với nguyên lý này chúng ta sẽ chuyển giao việc kiểm soát các objects cho một container xử lý. Thông thường khi cần dùng một object nào đó ta sẽ trực tiếp tạo thì nay ta sẽ không làm thế nữa mà chỉ đưa ra yêu cầu và container sẽ cung cấp các object cần thiết.
Spring IoC container chính là container sẽ implement IoC principle. Trong Spring thì interface org.springframework.context.ApplicationContext
đại diện cho Spring IoC container, nó sẽ có trách nhiệm khởi tạo, cấu hình và lắp ráp các Spring Beans
DI - Dependency Injection là một design pattern, một cách để implement IoC. DI là một process mà mỗi đối tượng sẽ định nghĩa những dependencies của chúng (những object mà chúng cần làm việc cùng), những dependencies đó sẽ được inject vào thông qua constructor, setter hoặc factory method.
DI giúp chương trình liên kết các thành phần của hệ thống lại với nhau, các module cấp thấp sẽ được inject vào module cấp cao (Nếu A gọi B thì A là module cấp cao và ngược lại). Với cách thức này chúng đã sẽ đạt được tính liên kết loose coupling thay vì tight coupling
Một dự án phần mềm được triển khai thông thường quá trình tạo mới sẽ chiếm khoảng 20-40%, effort còn lại sẽ là maintaince. Chính vì thế khi thiết kế chúng ta luôn cần liên kết loose coupling để: DỄ DÀNG MỞ RỘNG.
Cả BeanFactory
và ApplicationContext
đều là Spring container giúp quản lý và truy xuất Spring beans.
ApplicationContext
kế thừa BeanFactory
và cung cấp thêm những features khác. Ví dụ, ApplicationContext
hỗ trợ thêm: internationalization (i18n), event-driven architecture, JSF và JPA.BeanFactory
chỉ hỗ trợ load bean thông qua xml trong khi ApplicationContext
hỗ trợ cả xml và annotation.BeanFactory
sử dụng memory ít hơn ApplicationContext
, nên nó phù hợp với môi trường low-memory và có ít bean cần quản lý.BeanFactory
sử dụng cơ chế lazy initialization chỉ khởi tạo bean khi được request. Ngược lại, ApplicationContext
lại khởi tạo toàn bộ bean đã được config trong quá trình context start-up.Kết luận: BeanFactory
cung cấp các tính năng cơ bản của một contaiter trong khi ApplicationContext
cung cấp phong phú hơn các tính năng và được recommended sử dụng trong hầu hết các trường hợp
Spring support 2 loại DI chính: Constructor-based DI và Setter-based DI.
Ngoài ra còn một loại là Field-based DI, sử dụng @Autowired
đặt lên trên field muốn inject trong class, tuy nhiên loại này không được khuyến khích sử dụng
Những object được khởi tạo và quản lý bởi Spring IoC container được gọi là Spring Bean.
Scope | Description | |
---|---|---|
singleton |
Standard scope | (Default) Spring container chỉ tạo 1 bean instance duy nhất cho tất cả các request inject. |
prototype |
Standard scope | Spring container sẽ tạo mới bean instance mỗi khi có request inject bean đó.
prototype scope nên được sử dụng cho stateful bean và singleton scope sử dụng cho stateless bean. |
request |
Web scope | Spring container sẽ tạo bean instance với mỗi HTTP request. Khi request kết thúc thì những bean này sẽ bị loại bỏ. |
session |
Web scope | Spring container sẽ tạo bean instance với mỗi HTTP Session. Khi session bị loại bỏ thì những bean này sẽ bị loại bỏ. |
application |
Web scope |
Spring container sẽ tạo 1 bean instance cho toàn bộ web application. Scope này dễ nhầm lẫn với |
websocket | Web scope | Bean instance được khởi tạo sẽ được liên kết với vòng đời của một WebSocket session |
Có 2 cách thức khởi tạo Spring Bean
<bean>
tag, chỉ định type thông qua class attribute và name thông qua id/name attribute.@Component
Các annotation @Service
, @Controller
, @Repository
cũng có thể dùng đăng ký Spring Bean do chúng có compose @Component bên trong
@Service
: Annotation được sử dụng để chỉ định các class có vai trò xử lý các business logic và communicate với persistence layer.@Repository
: Annotation được sử dụng để chỉ định các class ở persistence layer có vai trò tương tác với database thực hiện CRUD@Controller
: Annotation được sử dụng để chỉ định các class có vai trò như là Controller trong mô hình MVC@Component
: Đây là general annotation được sử dụng để chỉ định các class có thể tạo bean, và
thông thường các class này không phù hợp với các annotations: @Controller
, @Service
, @Repository
Kết luận: Các annotations này hỗ trợ tạo bean và giúp chỉ định vai trò của các class trong application để giúp phân tách rõ nghĩa các layer của ứng dụng.
Spring container xác định bean phù hợp để inject vào dependent object theo thứ tự sau:
@Qualifier
được sử dụng để xác định bean nào được inject.@Qualifier
không được sử dụng thì những bean được đánh dấu @Primary
sẽ được ưu tiên inject hơn những bean còn lại.Kết luận: Nếu có từ 2 beans phù hợp data type trở lên và Spring container không thể xác định được bean nào để inject thì một lỗi: "APPLICATION FAILED TO START"
với nội dung dạng "required a single bean, but 2 were found"
sẽ được throw.
# | Spring Framework | Spring Boot |
---|---|---|
Khái niệm | Là một framework được build dựa trên nền Java, nó cung cấp rất nhiều các module hỗ trợ việc xây dựng Java applications. | Là một framework được build dựa trên nền Spring framework, nó giúp đơn giản hóa việc khởi tạo và phát triển Spring applications. |
Configuration | Spring framework yêu cầu tự cấu hình khá chi tiết và phức tạp | Spring boot cung cấp cơ chế auto-configuration giúp đơn giản hóa khởi tạo và developer có thể tập trung vào xử lý business. |
Standalone Applications | Spring framework chưa thể hỗ trợ tạo standalone applications | Spring boot hỗ trợ có thể tạo standalone applications, đóng gói thành jar và dễ dàng deploy, run |
Development time | Với Spring Boot ta có thể develop và test application dễ dàng và nhanh hơn vì không cần phải care đến nhiều các task configuration và setup |
Standalone Applications là các ứng dụng có thể độc lập thực thi mà không cần cài đặt thêm các dependencies hoặc config từ bên ngoài.
# | Model |
ModelMap |
ModelAndView |
---|---|---|---|
Mục đích sử dụng | [1] Cung cấp data (Model attributes) từ Controller layer đến View layer để rendering HTML. | ||
- | - | [2] Xác định view sẽ được response. | |
Vị trí sử dụng | Controller method argument | Controller method argument | Controller method return value |
Type | interface |
class |
class |
1 2 3 4 5 6 7 8 9 10 11 12 | @GetMapping("/showView") public String showView(Model model) { // Add an attribute model.addAttribute("greeting", "Welcome to Winzone.vn"); // Add a map attributes Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("interviewQuestion", "Question Spring MVC"); model.addAllAttributes(paramMap); return "viewPage"; } |
1 2 3 4 5 6 7 8 9 10 11 12 | @GetMapping("/showView") public String showView(ModelMap model) { // Add an attribute model.addAttribute("greeting", "Welcome to Winzone.vn"); // Add a map attributes Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("interviewQuestion", "Question Spring MVC"); model.addAllAttributes(paramMap); return "viewPage"; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @GetMapping("/showView") public ModelAndView showView() { Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("interviewQuestion", "Question Spring MVC"); ModelMap model = new ModelMap(); model.addAllAttributes(paramMap); ModelAndView modelAndView = new ModelAndView("viewPage"); modelAndView.addAllObjects(model); modelAndView.addObject("greeting", "Welcome to Winzone.vn"); return modelAndView; } |
1 2 3 4 5 6 7 8 9 10 11 12 | @GetMapping("/showView") public String showView(Model model) { // Add an attribute model.addAttribute("greeting", "Welcome to Winzone.vn"); // Add a map attributes Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("interviewQuestion", "Question Spring MVC"); model.addAllAttributes(paramMap); return "viewPage"; } |
1 2 3 4 5 6 7 8 9 10 11 12 | @GetMapping("/showView") public String showView(ModelMap model) { // Add an attribute model.addAttribute("greeting", "Welcome to Winzone.vn"); // Add a map attributes Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("interviewQuestion", "Question Spring MVC"); model.addAllAttributes(paramMap); return "viewPage"; } |
1 2 3 4 5 6 7 8 9 10 11 12 | @GetMapping("/showView") public ModelAndView showView(ModelMap model) { Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("interviewQuestion", "Question Spring MVC"); model.addAllAttributes(paramMap); ModelAndView modelAndView = new ModelAndView("viewPage"); modelAndView.addObject("greeting", "Welcome to Winzone.vn"); modelAndView.addAllObjects(model); return modelAndView; } |
# | addAttribute() |
addFlashAttribute() |
||
---|---|---|---|---|
Mục đích sử dụng | Send attribute từ Controller này sang một Controller khác qua Redirect | |||
Source demo |
|
|||
Kết quả |
Attribute value sẽ được gửi đến endpoint /showView?attribute=attributeValue
|
Attribute value sẽ lưu trong
|