Серия SpringSession — интеграция SpringBoot

Redis задняя часть контейнер

springSessionдаspringпроект в рамкахservletконтейнер реализованhttpSessionзаменитьspringSession, сосредоточиться на решенииsessionвопросы управления. Простая, быстрая и бесшовная интеграция в наши приложения. В этой статье используется случай, используяSpringBootинтегрироватьSpringSessionи использоватьRedisпрактика в качестве хранилищаSpringSessionиспользование.

Подготовка окружающей среды

потому что нужно использоватьRedisкак нижний слойSessionноситель для достижения распределенногоsession, так что нужно установитьRedis.

Установка Redis

1. ИзОфициальный сайтЗагрузите последнюю версиюRedis

2. Декомпрессия

tar zxvf redis-5.0.0.tar.gz

3. Скомпилируйте и протестируйте

 sudo make test

4. Скомпилируйте и установите

sudo make install

5. Проблемы с установкой

Если вы установили его ранее, повторили установку и не удалили полностью, будет сообщено о следующей ошибке

make[1]: *** [test] Error 1 
make: *** [test] Error 2

Чтобы устранить эту ошибку, выполните следующую инструкцию:

make distclean 
make 
make test

Правильная установочная поза выглядит следующим образом:

6. СтартRedisв вашейRedisВ каталоге установки естьredis-server, выполните команду скрипта:

Хорошо, поехали,RedisМонтажные работы завершены.

Подготовка проекта SpringBoot

Здесь мы проходим непосредственно черезIdeaпостроить нашSpringBootпроект.

File->New->Project : Spring Initializr

ХОРОШО,SpringBootПроект готов, вот подборка для созданияWebпроект.

интегрированный

Интеграция — это в основном введение зависимости, которая здесь требуетсяredisиsessionзависимость

импорт зависимостей

<dependencies>
    <!--redis 依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--sessions 依赖-->
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
</dependencies>

Настроить application.properties

#服务端口
server.port=8080
#redi主机地址
spring.redis.host=localhost
#redis服务端口
spring.redis.port=6379

# spring session使用存储类型,spirngboot默认就是使用redis方式,如果不想用可以填none。
spring.session.store-type=redis

Добавьте аннотацию @EnableRedisHttpSession в класс запуска.

@SpringBootApplication
@EnableRedisHttpSession
public class SpringBootSessionApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootSessionApplication.class, args);
    }
}

контрольная работа

Давайте напишемController

/**
 * SessionController
 * 
 * @author: glmapper@leishu
 * @since: 18/11/3 下午3:16
 * @version 1.0
 **/
@Controller
@RequestMapping(value = "/")
public class SessionController {
    
    @ResponseBody
    @RequestMapping(value = "/session")
    public Map<String, Object> getSession(HttpServletRequest request) {
        request.getSession().setAttribute("userName", "glmapper");
        Map<String, Object> map = new HashMap<>();
        map.put("sessionId", request.getSession().getId());
        return map;
    }
    
    @ResponseBody
    @RequestMapping(value = "/get")
    public String get(HttpServletRequest request) {
        String userName = (String) request.getSession().getAttribute("userName");
        return userName;
    }
}

Результаты теста

запускатьSpringBootпроекта, затем введите адрес в браузереhttp://локальный:8080/сеанс;

Соответствующая реализация здесь - это то, что мы имеем вышеControllerпервый метод вgetSession, этот методsessionЗначение устанавливается в .

Ниже выполняем:http://localhost:8080/getвот изsessionЗначение в:

Уже,SpringBootИнтегрироватьSpringSessionпроцесс завершен. Здесь мы просто вводим зависимости, а затем делаем простую настройку, так как наши запросыSpringSessionиметь дело с этим? Исходя из нашего последовательного понимания, дляServletканонический контейнер (SpringBootиспользуя встроенныйTomcat), первый обрабатываемый запросFilter. мы основаны наSpring+SpringMvcВо время разработки этого стека технологий, если нам понадобится управление разрешениями, мыFilterили перехватчик. Но похоже, что мы здесь ничего не делаем, но запрос действительно обрабатывается.SpringSessionобработанный. Хорошо, давайте посмотрим.

Как SpringSession обрабатывает запросы?

Скриншот выше должен быть всем знаком, даSpringBootЖурнал запуска ; красное поле на рисунке выше показывает текущую регистрацию приложения.Filterинформации, отсюда видно, что есть иsessionСвязанныйFilter:sessionRepositoryFilter;этоbeanСоответствующие классы:

org.springframework.boot.autoconfigure.session.SessionRepositoryFilterConfiguration.ConditionalOnBean=
org.springframework.session.web.http.SessionRepositoryFilter

нашел здесь

участие здесьSpringBootАвтоматическая конфигурация изspring-boot-autoconfigСкачать пакетspring-autoconfigure-metadata.propertiesфайл конфигурации, а затем получить всю информацию, которая поддерживает автоматическую настройку;SpringSessionТакже в нем. Как загрузить и зарегистрироваться выходит за рамки данной статьи, продолжаем разбиратьSpringSessionпроцесс обработки.

Обработка SpringSession

сверхуSpringBootПроцесс запуска мы нашли дескрипторsessionизFilter, а затем знать, что он зарегистрирован в текущем контейнере с помощью автоматической настройки и обрабатывает запросы.

@Order(SessionRepositoryFilter.DEFAULT_ORDER)
public class SessionRepositoryFilter<S extends Session> 
extends OncePerRequestFilter {

отSessionRepositoryFilterИз определения:

  • 1. используетсяOrder, и настроено с небольшим значением (Integer.MIN_VALUE + 50), чтобы убедиться, чтоsessionизFilterсуществуетFilterЦепочка выполняется первой.
  • 2. ИнтегрированныйOncePerRequestFilter, чтобы гарантировать, что только один проход в запросеfilter, не повторяясь

ПочемуsessionизFilterБыть в приоритете? Поскольку наш запрос завернут, еслиSessionRepositoryFilterОтсутствие приоритета запросов может привести к непоследовательному поведению последующих запросов, что включает в себяspringSessionБеспроблемная замена серверов приложенийrequestПринцип:

  • 1. НастроитьFilter,выполнитьdoFilterметод
  • 2. НаследованиеHttpServletRequestWrapper,HttpServletResponseWrapperкласс, переопределитьgetSessionи другие связанные методы (в этих методах вызов связанныхsessionкласс эксплуатации контейнера хранения).
  • 3. Настроитьrequestиresponseклассы и передавать их отдельно в цепочку фильтров
  • 4. ПоместитеfilterНастроен на первую позицию в цепочке фильтров

Хорошо, зная эти предыстории, давайте проследим весь процесс обработки.

1. Точка останова для doFilterInternal

можно увидеть отсюдаrequestиresponseКласс завернут.

2. Точка останова для getSession

вот изRedisвозьми насsessionместо данных

  • Начните с нашего текущегоservletПолучите его в контейнере, если вы его получите, верните его напрямую

  • идти сRedisПринимать

    Здесь будет обработка кеша, не каждый разReidsПроверьте один раз в середине, избегайте один раз сReidsвзаимодействие.

    • Если кеш в настоящее время существует в кеше контейнера приложения, он будет напрямую возвращать текущий кешированныйsession
    • Если нет, получить его из запросаsessionId, а по текущемуsessionIdидти сReidsНайти вsessionданные
    • обновить кешsession,sessionId,requestedSessionCachedОжидание статуса данных
  • еслиRedisЕсли да, обновитеsessionсоответствующая информация и возврат

  • еслиReidsне обнаружено, согласноcreateопределить, создавать ли новуюsession.

Точка останова для чтенияCookieValues

SpringSessionОбеспечивает как сохранение, так и передачуSessionIdобразом, один основан наCookie, один основан наHeaderиз.SpringSessionЗначение по умолчанию основано наCookieПуть.readCookieValuesкак достичьCookieполучено вsessionIdиз.

Процесс на самом деле довольно прост, начиная сrequestПолучить все данные, переносимые текущим запросом, вCookieинформацию, а затем сопоставьтеcookieNameза“SESSION”изCookieразобрать.

Точка останова на RedisOperationsSessionRepository -> getSession

вот изRedisПриниматьsessionместо данных

  • в соответствии сsessionIdотRedisвзято изentriesданные
  • ПостроитьRedisSessionи вернуться

Точка останова для фиксации сеанса

commitSessionфункционировать черезHttpSessionIdResolverбудетsessionIdнаписатьresponseи сделать его постоянным.

здесьsessionНа самом деле статус обновился, типа сбросsessionсрок годности и др.sessionФиксация на самом деле означает, что текущий запрос был обработан.

резюме

В этой статье сначала описывается, как использоватьSpringBootинтегрированныйSpringSession, и сRedisкак хранилище. Затем просто проанализируйтеSpringSessionПроцесс обработки этой бумагиSpringSessionОтсутствует глубокий анализ принципиальной частиSpringSessionпринцип.