Поиск объекта в сессии Sprign MVC @Scope

152
13 сентября 2019, 09:50

При каждом запросе модели Accaunt постоянно осуществляется поиск в БД. Хочу инициализировать его всего один раз. Я правильно реализовал или нет? и будут ли ошибки при загрузке сервлетов, ведь private Accaunt accaunt не имеет @Scope.

@ControllerAdvice(basePackages = "com.work.controller.accaunt")
public class CtrAddAccaunt {
    @Autowired private DaoAccaunt daoAccaunt;
    private Accaunt accaunt;
    @ModelAttribute(SessionAttr.ACCAUNT) 
    public Accaunt getAccaunt(Authentication authentication) {
        System.out.println("поиск аккаунта + "+authentication.getName());
        if (accaunt != null) {
            return accaunt;
        } else {
            return daoAccaunt.getAccaunt(authentication.getName());
        }        
    }
}
Answer 1

У вас private Accaunt accaunt; не используется вообще.

Полагаю, вы хотели сделать так:

@ModelAttribute(SessionAttr.ACCAUNT) 
public Accaunt getAccaunt(Authentication authentication) {
    System.out.println("поиск аккаунта + "+authentication.getName());
    if (accaunt == null) {
        account = daoAccaunt.getAccaunt(authentication.getName());
    }
    return account;        
}

Но эта реализация сохранит account один раз - а вам нужно сохранять account для каждого authentication.getName() - использовать HashMap, например.

Не работал подробно с MVC, но, думаю, всё равно так работать не будет.
@Scope нужно указывать над классом CrtAddAccount, чтобы добиться нужного эффекта. Но могут возникнуть другие проблемы..

Лучшее решение в вашем случае - использование spring cache.
Вот пример его использования при обращении к БД
А вот краткое описание на SO

П.С. Однако необходимость использования кэширования обращения к базе возникает не часто, думаю, стоит её использовать с осторожностью и пониманием дела

Answer 2

Проблема оказалась в том, что @ControllerAdvice добовлял ко всем контроллерам в пакете атрибут ACCAUNT.

Нужно было просто указать не пакет, а конкретные контроллеры в переменную assignableTypes:

@ControllerAdvice(assignableTypes = {
    CtrAccauntPageUser.class,
    CtrAccauntPageCompany.class
})
public class CtrAdviceAccaunt {
    @Autowired private DaoAccaunt daoAccaunt;
    @ModelAttribute(SessionAttr.ACCAUNT) 
    public Accaunt getAccaunt(Authentication authentication, HttpServletRequest request) {
        System.out.println("httpServletRequest + "+request.getRequestURI());
        return daoAccaunt.getAccaunt(authentication.getName());       
    }
}

Теперь @ModelAttribute(SessionAttr.ACCAUNT) виден только в тех контроллерах, которые я указал.

Можно сделать вывод, что:

  1. basePackages - для сканирования пакета и добавления @ModelAttribute во все контроллеры находящиеся в данном пакете;
  2. basePackagesClasses - для сканирования родительского пакета указанного контроллера и добавления @ModelAttribute во все контроллеры находящиеся в данном пакете;
  3. assignableTypes - для добавления @ModelAttribute в конкретный контроллер.
READ ALSO
Изменение DOM из модуля JS

Изменение DOM из модуля JS

Пишу приложение на nwjs

155
В битрикс не работает $APPLICATION->ShowHead()

В битрикс не работает $APPLICATION->ShowHead()

В head прописан $APPLICATION->ShowHead(), но не подключает библиотеки для неавторизованных пользователей, зато для админа - все окВ консоли ошибки:

136
Вывод видео с карты видео захвата в тег <video> html?

Вывод видео с карты видео захвата в тег <video> html?

Есть устройство, к нему подключаем карту видео захвата (пока с ней, но в идеале напрямую через vga)Устройство и карта на стороне клиента

121