@bigmag
JAVA Developer

Объясните как Spring в одиночные бины подставляет бины @RequestScope и @SessionScope?

Всем привет! Изучаю книгу "Spring Quick".
Постороннее изображение удалено модератором.
9.2. ИСПОЛЬЗОВАНИЕ ОБЛАСТИ ВИДИМОСТИ В РАМКАХ СЕССИИ В ВЕБ-ПРИЛОЖЕНИЯХ SPRING
Проект-пример : sq-ch9-ex2

import org.springframework.stereotype.Service;
import org.springframework.web.context.annotation.SessionScope;

@Service
@SessionScope
public class LoggedUserManagementService {
    private String username;
    public String xxx = "123321";
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
}


@Controller
public class MainController {

    private final LoggedUserManagementService loggedUserManagementService;

    public MainController(LoggedUserManagementService loggedUserManagementService) {
        this.loggedUserManagementService = loggedUserManagementService;
        System.out.println("xxx: " + loggedUserManagementService.xxx);
        System.out.println(loggedUserManagementService.xxx);
    }

    @GetMapping("/main")
    public String home(@RequestParam(required = false) String logout, Model model) {

        if (logout != null) {
            loggedUserManagementService.setUsername(null);
        }

        if (loggedUserManagementService.getUsername() == null) {
            return "redirect:/";
        }

        model.addAttribute("username", loggedUserManagementService.getUsername());
        return "main.html";
    }
}


Ход моих мыслей: В момент запуска Spring создает Бины и инжектит в них зависимости. Класс "MainController" - одиночка, имеет поле final "LoggedUserManagementService".
Класс "LoggedUserManagementService" - это Бин @SessionScope - создается в момент открытия новой сессии.
Когда мы запустили приложение Spring, бин класса MainController создался сразу, а бин "LoggedUserManagementService" нет, потому что еще не было сессий. Сразу после запуска поле loggedUserManagementService класса MainController равно null.
Теперь когда я открываю http-сессию, вдруг откуда не возьмись в поле "LoggedUserManagementService" класса "MainController" появляется Бин. Мне не понятно как он туда попал?
А если будет 100 сессий одновременно? Получается в Контексте будет бин-одиночка "MainController", но с разными бинами в поле «LoggedUserManagementService» для каждой сессии? Как это возможно?

ВОПРОС: Как в классе "MainController" заполняется поле "loggedUserManagementService"?
  • Вопрос задан
  • 116 просмотров
Решения вопроса 1
xez
@xez
TL Junior Roo
Если остановиться дебагером где-то в методе home, то можно обнаружить, что в поле loggedUserManagementService содержится какой-то странный объект:
64e6e88c1f75d026359718.png

На самом деле, спринг инжектит не сами экземпляры пользовательских объектов, а обертки (прокси) над ними, а уже в этих обертках могут использоваться разные экземпляры пользовательских объектов. Т.о. достигается поведение, предполагаемое аннотациями @RequestScope, @SessionScope, @Lazy и прочее..

Погуглить по теме

JDK dynamic proxy
Spring AOP
CGLIB
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы