日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringSession实战项目(基于SpringBoot项目)【附源码】

發布時間:2023/12/14 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringSession实战项目(基于SpringBoot项目)【附源码】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python實戰社群

Java實戰社群

長按識別下方二維碼,按需求添加

掃碼關注添加客服

進Python社群▲

掃碼關注添加客服

進Java社群

作者丨懷瑾握瑜

來源鏈接:

https://www.cnblogs.com/lxyit/p/9720159.html

spring-boot 整合 spring-session 的自動配置可謂是開箱即用,極其簡潔和方便。這篇文章即介紹 spring-boot 整合 spring-session,這里只介紹基于 RedisSession 的實戰。

考慮到 RedisSession 模塊與 spring-session v2.0.6 版本的差異很小,且能夠與 spring-boot v2.0.0 兼容,所以實戰篇是基于 spring-boot v2.0.0 基礎上配置 spring-session。

配置 spring-session

引入 spring-session 的 pom 配置,由于 spring-boot 包含 spring-session 的 starter 模塊,所以 pom 中依賴:

<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId> </dependency>

編寫 spring boot 啟動類 SessionExampleApplication

/***?啟動類**?@author?huaijin*/ @SpringBootApplication public?class?SessionExampleApplication?{public?static?void?main(String[]?args)?{SpringApplication.run(SessionExampleApplication.class,?args);} }

配置 application.yml

spring:session:redis:flush-mode:?on_savenamespace:?session.examplecleanup-cron:?0?*?*?*?*?*store-type:?redistimeout:?1800redis:host:?localhostport:?6379jedis:pool:max-active:?100max-wait:?10max-idle:?10min-idle:?10database:?0

編寫 controller

編寫登錄控制器,登錄時創建 session,并將當前登錄用戶存儲 sesion 中。登出時,使 session 失效。

/***?登錄控制器**?@author?huaijin*/ @RestController public?class?LoginController?{private?static?final?String?CURRENT_USER?=?"currentUser";/***?登錄**?@param?loginVo?登錄信息**?@author?huaijin*/@PostMapping("/login.do")public?String?login(@RequestBody?LoginVo?loginVo,?HttpServletRequest?request)?{UserVo?userVo?=?UserVo.builder().userName(loginVo.getUserName()).userPassword(loginVo.getUserPassword()).build();HttpSession?session?=?request.getSession();session.setAttribute(CURRENT_USER,?userVo);System.out.println("create?session,?sessionId?is:"?+?session.getId());return?"ok";}/***?登出**?@author?huaijin*/@PostMapping("/logout.do")public?String?logout(HttpServletRequest?request)?{HttpSession?session?=?request.getSession(false);session.invalidate();return?"ok";} }

編寫查詢控制器,在登錄創建 session 后,使用將 sessionId 置于 cookie 中訪問。如果沒有 session 將返回錯誤。

/***?查詢**?@author?huaijin*/ @RestController @RequestMapping("/session") public?class?QuerySessionController?{@GetMapping("/query.do")public?String?querySessionId(HttpServletRequest?request)?{HttpSession?session?=?request.getSession(false);if?(session?==?null)?{return?"error";}System.out.println("current's?user?is:"?+?session.getId()?+??"in?session");return?"ok";} }

編寫 Session 刪除事件監聽器

Session 刪除事件監聽器用于監聽登出時使 session 失效的事件源。

/***?session事件監聽器**?@author?huaijin*/ @Component public?class?SessionEventListener?implements?ApplicationListener<SessionDeletedEvent>?{private?static?final?String?CURRENT_USER?=?"currentUser";@Overridepublic?void?onApplicationEvent(SessionDeletedEvent?event)?{Session?session?=?event.getSession();UserVo?userVo?=?session.getAttribute(CURRENT_USER);System.out.println("invalid?session's?user:"?+?userVo.toString());} }

驗證測試

編寫 spring-boot 測試類,測試 controller,驗證 spring-session 是否生效。

/***?測試Spring-Session:*?1.登錄時創建session*?2.使用sessionId能正常訪問*?3.session過期銷毀,能夠監聽銷毀事件**?@author?huaijin*/ @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public?class?SpringSessionTest?{@Autowiredprivate?MockMvc?mockMvc;@Testpublic?void?testLogin()?throws?Exception?{LoginVo?loginVo?=?new?LoginVo();loginVo.setUserName("admin");loginVo.setUserPassword("admin@123");String?content?=?JSON.toJSONString(loginVo);//?mock登錄ResultActions?actions?=?this.mockMvc.perform(post("/login.do").content(content).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(content().string("ok"));String?sessionId?=?actions.andReturn().getResponse().getCookie("SESSION").getValue();//?使用登錄的sessionId?mock查詢this.mockMvc.perform(get("/session/query.do").cookie(new?Cookie("SESSION",?sessionId))).andExpect(status().isOk()).andExpect(content().string("ok"));//?mock登出this.mockMvc.perform(post("/logout.do").cookie(new?Cookie("SESSION",?sessionId))).andExpect(status().isOk()).andExpect(content().string("ok"));} }

測試類執行結果:

create?session,?sessionId?is:429cb0d3-698a-475a-b3f1-09422acf2e9c current's?user?is:429cb0d3-698a-475a-b3f1-09422acf2e9cin?session invalid?session's?user:UserVo{userName='admin',?userPassword='admin@123'

登錄時創建 Session,存儲當前登錄用戶。然后在以登錄響應返回的 SessionId 查詢用戶。最后再登出使 Session 過期。

spring-boot 整合 spring-session 自動配置原理

前兩篇文章介紹 spring-session 原理時,總結 spring-session 的核心模塊。這節中探索 spring-boot 中自動配置如何初始化 spring-session 的各個核心模塊。

spring-boot-autoconfigure 模塊中包含了 spinrg-session 的自動配置。包 org.springframework.boot.autoconfigure.session 中包含了 spring-session 的所有自動配置項。

其中 RedisSession 的核心配置項是 RedisHttpSessionConfiguration 類。

@Configuration @ConditionalOnClass({?RedisTemplate.class,?RedisOperationsSessionRepository.class?}) @ConditionalOnMissingBean(SessionRepository.class) @ConditionalOnBean(RedisConnectionFactory.class) @Conditional(ServletSessionCondition.class) @EnableConfigurationProperties(RedisSessionProperties.class) class?RedisSessionConfiguration?{@Configurationpublic?static?class?SpringBootRedisHttpSessionConfigurationextends?RedisHttpSessionConfiguration?{//?加載application.yml或者application.properties中自定義的配置項://?命名空間:用于作為session redis key的一部分// flushmode:session寫入redis的模式//?定時任務時間:即訪問redis過期鍵的定時任務的cron表達式@Autowiredpublic?void?customize(SessionProperties?sessionProperties,RedisSessionProperties?redisSessionProperties)?{Duration?timeout?=?sessionProperties.getTimeout();if?(timeout?!=?null)?{setMaxInactiveIntervalInSeconds((int)?timeout.getSeconds());}setRedisNamespace(redisSessionProperties.getNamespace());setRedisFlushMode(redisSessionProperties.getFlushMode());setCleanupCron(redisSessionProperties.getCleanupCron());}}}

RedisSessionConfiguration 配置類中嵌套 SpringBootRedisHttpSessionConfiguration 繼承了 RedisHttpSessionConfiguration 配置類。首先看下該配置類持有的成員。

@Configuration @EnableScheduling public?class?RedisHttpSessionConfiguration?extends?SpringHttpSessionConfigurationimplements?BeanClassLoaderAware,?EmbeddedValueResolverAware,?ImportAware,SchedulingConfigurer?{//?默認的cron表達式,application.yml可以自定義配置static?final?String?DEFAULT_CLEANUP_CRON?=?"0?*?*?*?*?*";//?session的有效最大時間間隔,?application.yml可以自定義配置private?Integer?maxInactiveIntervalInSeconds?=?MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;//?session在redis中的命名空間,主要為了區分session,application.yml可以自定義配置private?String?redisNamespace?=?RedisOperationsSessionRepository.DEFAULT_NAMESPACE;//?session寫入Redis的模式,application.yml可以自定義配置private?RedisFlushMode?redisFlushMode?=?RedisFlushMode.ON_SAVE;//?訪問過期Session集合的定時任務的定時時間,默認是每整分運行任務private?String?cleanupCron?=?DEFAULT_CLEANUP_CRON;private?ConfigureRedisAction?configureRedisAction?=?new?ConfigureNotifyKeyspaceEventsAction();//?spring-data-redis的redis連接工廠private?RedisConnectionFactory?redisConnectionFactory;//?spring-data-redis的RedisSerializer,用于序列化session中存儲的attributesprivate?RedisSerializer<Object>?defaultRedisSerializer;//?session時間發布者,默認注入的是AppliationContext實例private?ApplicationEventPublisher?applicationEventPublisher;//?訪問過期session鍵的定時任務的調度器private?Executor?redisTaskExecutor;private?Executor?redisSubscriptionExecutor;private?ClassLoader?classLoader;private?StringValueResolver?embeddedValueResolver; }

該配置類中初始化了 RedisSession 的最為核心模塊之一 RedisOperationsSessionRepository。

@Bean public?RedisOperationsSessionRepository?sessionRepository()?{//?創建RedisOperationsSessionRepositoryRedisTemplate<Object,?Object>?redisTemplate?=?createRedisTemplate();RedisOperationsSessionRepository?sessionRepository?=?new?RedisOperationsSessionRepository(redisTemplate);//?設置Session Event發布者。如果對此迷惑,傳送門:https://www.cnblogs.com/lxyit/p/9719542.htmlsessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);if?(this.defaultRedisSerializer?!=?null)?{sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);}//?設置默認的Session最大有效期間隔sessionRepository.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);//?設置命名空間if?(StringUtils.hasText(this.redisNamespace))?{sessionRepository.setRedisKeyNamespace(this.redisNamespace);}//?設置寫redis的模式sessionRepository.setRedisFlushMode(this.redisFlushMode);return?sessionRepository; }

同時也初始化了 Session 事件監聽器 MessageListener 模塊

@Bean public?RedisMessageListenerContainer?redisMessageListenerContainer()?{//?創建MessageListener容器,這屬于spring-data-redis范疇,略過RedisMessageListenerContainer?container?=?new?RedisMessageListenerContainer();container.setConnectionFactory(this.redisConnectionFactory);if?(this.redisTaskExecutor?!=?null)?{container.setTaskExecutor(this.redisTaskExecutor);}if?(this.redisSubscriptionExecutor?!=?null)?{container.setSubscriptionExecutor(this.redisSubscriptionExecutor);}//?模式訂閱redis的__keyevent@*:expired和__keyevent@*:del通道,//?獲取redis的鍵過期和刪除事件通知container.addMessageListener(sessionRepository(),Arrays.asList(new?PatternTopic("__keyevent@*:del"),new?PatternTopic("__keyevent@*:expired")));//?模式訂閱redis的${namespace}:event:created:*通道,當該向該通道發布消息,//?則MessageListener消費消息并處理container.addMessageListener(sessionRepository(),Collections.singletonList(new?PatternTopic(sessionRepository().getSessionCreatedChannelPrefix()?+?"*")));return?container; }

上篇文章中介紹到的 spring-session event 事件原理,spring-session 在啟動時監聽 Redis 的 channel,使用 Redis 的鍵空間通知處理 Session 的刪除和過期事件和使用 Pub/Sub 模式處理 Session 創建事件。

關于 RedisSession 的存儲管理部分已經初始化,但是 spring-session 的另一個基礎設施模塊 SessionRepositoryFilter 是在 RedisHttpSessionConfiguration 父類 SpringHttpSessionConfiguration 中初始化。

@Bean public?<S?extends?Session>?SessionRepositoryFilter<??extends?Session>?springSessionRepositoryFilter(SessionRepository<S>?sessionRepository)?{SessionRepositoryFilter<S>?sessionRepositoryFilter?=?new?SessionRepositoryFilter<>(sessionRepository);sessionRepositoryFilter.setServletContext(this.servletContext);sessionRepositoryFilter.setHttpSessionIdResolver(this.httpSessionIdResolver);return?sessionRepositoryFilter; }

spring-boot 整合 spring-session 配置的層次:

RedisSessionConfiguration|_?_?SpringBootRedisHttpSessionConfiguration|_?_?RedisHttpSessionConfiguration|_?_?SpringHttpSessionConfiguration

回顧思考 spring-boot 自動配置 spring-session,非常合理。

  • SpringHttpSessionConfiguration 是 spring-session 本身的配置類,與 spring-boot 無關,畢竟 spring-session 也可以整合單純的 spring 項目,只需要使用該 spring-session 的配置類即可。

  • RedisHttpSessionConfiguration 用于配置 spring-session 的 Redission,畢竟 spring-session 還支持其他的各種 session:Map/JDBC/MogonDB 等,將其從 SpringHttpSessionConfiguration 隔離開來,遵循開閉原則和接口隔離原則。但是其必須依賴基礎的 SpringHttpSessionConfiguration,所以使用了繼承。RedisHttpSessionConfiguration 是 spring-session 和 spring-data-redis 整合配置,需要依賴 spring-data-redis。

  • SpringBootRedisHttpSessionConfiguration 才是 spring-boot 中關鍵配置

  • RedisSessionConfiguration 主要用于處理自定義配置,將 application.yml 或者 application.properties 的配置載入。

Tips:

配置類也有相當強的設計模式。遵循開閉原則:對修改關閉,對擴展開放。遵循接口隔離原則:變化的就要單獨分離,使用不同的接口隔離。SpringHttpSessionConfiguration 和 RedisHttpSessionConfiguration 的設計深深體現這兩大原則。

參考

Spring Session參考文:https://spring.io/projects/spring-session#samples

本文例子源碼

https://github.com/lixyou/spring-boot-example/tree/master/session-example

程序員專欄?掃碼關注填加客服?長按識別下方二維碼進群


近期精彩內容推薦:??

?外包程序員入職螞蟻金服被質疑,網友:人生污點

?11?月全國程序員平均工資出爐

?棄用 Notepad++,還有 5 款更牛逼的選擇!

?福利!手把手教你Python爬取女神套圖


在看點這里好文分享給更多人↓↓

總結

以上是生活随笔為你收集整理的SpringSession实战项目(基于SpringBoot项目)【附源码】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。