Top những câu hỏi phỏng vấn Spring - 01

  • Phuong Dang
  • 08/Nov/2022
spring
  1. So sánh Spring IoC và DI trong Spring?
  2. So sánh BeanFactory và ApplicationContext?
  3. Có mấy loại DI trong Spring?
  4. Spring Bean là gì?
  5. Spring Bean có những scope nào?
  6. Có những cách nào để tạo Spring Bean?
  7. So sánh annotation: @Service, @Controller, @Repository, và @Component.
  8. Spring container xác định bean để inject theo thứ tự nào?
  9. So sánh Spring framework và Spring Boot?
  10. So sánh Model, ModelMap và ModelAndView
  11. So sánh addAttribute() và addFlashAttribute() trong RedirectAttributes

Dưới đây là tổng hợp những câu hỏi phỏng vấn Spring cho đối tượng Fresher.

  • Spring Boot 2.7.5
  • Spring MVC version 5.3.2

1. So sánh Inversion of Control (IoC) và Dependency Injection (DI) trong Spring?

Trong Spring, Inversion of Control (IoC)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

tight coupling and loose coupling
Các thành phần của hệ thống càng liên kết chặt chẽ càng khó thay đổi và mở rộng

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.

2. So sánh BeanFactory và ApplicationContext?

Cả BeanFactoryApplicationContext đều là Spring container giúp quản lý và truy xuất Spring beans.

  • Features: 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.
  • Configuration: BeanFactory chỉ hỗ trợ load bean thông qua xml trong khi ApplicationContext hỗ trợ cả xml và annotation.
  • Performance: 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ý.
  • Lazy Initialization: Mặc định, 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

3. Có mấy loại DI trong Spring?

Spring support 2 loại DI chính: Constructor-based DISetter-based DI.

  • Constructor-based DI: Dependency sẽ được inject thông qua argument của constructor. Nên sử dụng trong trường hợp dependency là required.
  • Setter-based DI: Dependency sẽ được inject thông qua argument của setter method. Nên sử dụng trong trường hợp dependency là optional.

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

4. Spring bean là gì?

Những object được khởi tạo và quản lý bởi Spring IoC container được gọi là Spring Bean.

5. Spring Bean có những scope nào?

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 singleton scope, điểm khác nhau đó là singleton scope có tính duy nhất ở level ApplicationContext, còn application scope lại có tính duy nhất ở level ServletContext

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

6. Có những cách nào để tạo Spring Bean?

Có 2 cách thức khởi tạo Spring Bean

  • XML-based configuration: Sử dụng <bean> tag, chỉ định type thông qua class attribute và name thông qua id/name attribute.
  • Annotation-based configuration
    • Sử dụng Annotation class level: @Component
    • Sử dụng Annotation method level: @Bean + đặt trong 1 class có @Configuration

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

7. So sánh annotation: @Service, @Repository, @Controller, và @Component

  • @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.

8. Spring container xác định bean để inject theo thứ tự nào?

Spring container xác định bean phù hợp để inject vào dependent object theo thứ tự sau:

  1. Type matching: Spring sẽ cố gắng match data type của dependency object và data type của bean. Nếu chỉ có 1 bean matching thì nó sẽ được inject.
  2. Qualifier: Nếu có nhiều bean matching data type với dependency object thì @Qualifier được sử dụng để xác định bean nào được inject.
  3. Primary: Nếu @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.
  4. Named: Nếu sau step 3, vẫn có nhiều bean có thể inject thì Spring sẽ check bean name để inject.

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.

9. So sánh Spring framework và Spring Boot?

# 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.

10. So sánh Model, ModelMap và ModelAndView

# 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
01. Model
 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";
    }
    
02. ModelMap
 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";
        }
    
03. ModelAndView
 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;
    }
    

01. Model
 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";
    }
    
02. ModelMap
 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";
        }
    
03. ModelAndView
 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;
    }
    

11. So sánh addAttribute() và addFlashAttribute() trong RedirectAttributes

# addAttribute() addFlashAttribute()
Mục đích sử dụng Send attribute từ Controller này sang một Controller khác qua Redirect
Source demo
1
2
3
4
5
6
7
8
9
@PostMapping("/add")
public ModelAndView add(RedirectAttributes redirectAttributes) {
	// TODO: Validate and save object

	redirectAttributes.addAttribute("attribute", "attributeValue");
	redirectAttributes.addFlashAttribute("flashAttribute", "flashAttributeValue");

	return new ModelAndView("redirect:/showView");
}
Kết quả

Attribute value sẽ được gửi đến endpoint /showView thông qua query string

/showView?attribute=attributeValue

Attribute value sẽ lưu trong session và redirect đến endpoint /showView.

session attribute sẽ bị xóa sau khi request /showView được thực hiện.