├── .gitignore ├── .travis.yml ├── Changelog.md ├── LICENSE ├── README.md ├── TODO.md ├── pom.xml ├── redisson-spring-boot-autoconfigure ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── github │ │ └── trang │ │ └── redisson │ │ └── autoconfigure │ │ ├── RedissonAutoConfiguration.java │ │ ├── RedissonProperties.java │ │ ├── RedissonSpringAutoConfiguration.java │ │ ├── RedissonSpringProperties.java │ │ └── enums │ │ ├── AddressResolverGroupFactoryType.java │ │ ├── CodecType.java │ │ ├── LoadBalancerType.java │ │ └── RedissonType.java │ └── resources │ └── META-INF │ ├── additional-spring-configuration-metadata.json │ └── spring.factories └── redisson-spring-boot-starter ├── pom.xml └── src └── main └── resources └── META-INF └── spring.provides /.gitignore: -------------------------------------------------------------------------------- 1 | ### Extra 2 | rebel.xml 3 | 4 | ### Maven template 5 | target/ 6 | pom.xml.tag 7 | pom.xml.releaseBackup 8 | pom.xml.versionsBackup 9 | pom.xml.next 10 | release.properties 11 | dependency-reduced-pom.xml 12 | buildNumber.properties 13 | .mvn/timing.properties 14 | 15 | # Exclude maven wrapper 16 | !/.mvn/wrapper/maven-wrapper.jar 17 | ### macOS template 18 | *.DS_Store 19 | .AppleDouble 20 | .LSOverride 21 | 22 | # Icon must end with two \r 23 | Icon 24 | 25 | 26 | # Thumbnails 27 | ._* 28 | 29 | # Files that might appear in the root of a volume 30 | .DocumentRevisions-V100 31 | .fseventsd 32 | .Spotlight-V100 33 | .TemporaryItems 34 | .Trashes 35 | .VolumeIcon.icns 36 | .com.apple.timemachine.donotpresent 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | ### Example user template template 45 | ### Example user template 46 | 47 | # IntelliJ project files 48 | .idea 49 | *.iml 50 | out 51 | gen### Java template 52 | *.class 53 | 54 | # BlueJ files 55 | *.ctxt 56 | 57 | # Mobile Tools for Java (J2ME) 58 | .mtj.tmp/ 59 | 60 | # Package Files # 61 | *.jar 62 | *.war 63 | *.ear 64 | 65 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 66 | hs_err_pid* 67 | ### JDeveloper template 68 | # default application storage directory used by the IDE Performance Cache feature 69 | .data/ 70 | 71 | # used for ADF styles caching 72 | temp/ 73 | 74 | # default output directories 75 | classes/ 76 | deploy/ 77 | javadoc/ 78 | 79 | # lock file, a part of Oracle Credential Store Framework 80 | cwallet.sso.lck### Eclipse template 81 | 82 | .metadata 83 | bin/ 84 | tmp/ 85 | *.tmp 86 | *.bak 87 | *.swp 88 | *~.nib 89 | local.properties 90 | .settings/ 91 | .loadpath 92 | .recommenders 93 | 94 | # Eclipse Core 95 | .project 96 | 97 | # External tool builders 98 | .externalToolBuilders/ 99 | 100 | # Locally stored "Eclipse launch configurations" 101 | *.launch 102 | 103 | # PyDev specific (Python IDE for Eclipse) 104 | *.pydevproject 105 | 106 | # CDT-specific (C/C++ Development Tooling) 107 | .cproject 108 | 109 | # JDT-specific (Eclipse Java Development Tools) 110 | .classpath 111 | 112 | # Java annotation processor (APT) 113 | .factorypath 114 | 115 | # PDT-specific (PHP Development Tools) 116 | .buildpath 117 | 118 | # sbteclipse plugin 119 | .target 120 | 121 | # Tern plugin 122 | .tern-project 123 | 124 | # TeXlipse plugin 125 | .texlipse 126 | 127 | # STS (Spring Tool Suite) 128 | .springBeans 129 | 130 | # Code Recommenders 131 | .recommenders/ 132 | ### JetBrains template 133 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 134 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 135 | 136 | # User-specific stuff: 137 | .idea/workspace.xml 138 | .idea/tasks.xml 139 | 140 | # Sensitive or high-churn files: 141 | .idea/dataSources/ 142 | .idea/dataSources.ids 143 | .idea/dataSources.xml 144 | .idea/dataSources.local.xml 145 | .idea/sqlDataSources.xml 146 | .idea/dynamic.xml 147 | .idea/uiDesigner.xml 148 | 149 | # Gradle: 150 | .idea/gradle.xml 151 | .idea/libraries 152 | 153 | # Mongo Explorer plugin: 154 | .idea/mongoSettings.xml 155 | 156 | ## File-based project format: 157 | *.iws 158 | 159 | ## Plugin-specific files: 160 | 161 | # IntelliJ 162 | /out/ 163 | 164 | # mpeltonen/sbt-idea plugin 165 | .idea_modules/ 166 | 167 | # JIRA plugin 168 | atlassian-ide-plugin.xml 169 | 170 | # Crashlytics plugin (for Android Studio and IntelliJ) 171 | com_crashlytics_export_strings.xml 172 | crashlytics.properties 173 | crashlytics-build.properties 174 | fabric.properties 175 | ### Windows template 176 | # Windows image file caches 177 | Thumbs.db 178 | ehthumbs.db 179 | 180 | # Folder config file 181 | Desktop.ini 182 | 183 | # Recycle Bin used on file shares 184 | $RECYCLE.BIN/ 185 | 186 | # Windows Installer files 187 | *.cab 188 | *.msi 189 | *.msm 190 | *.msp 191 | 192 | # Windows shortcuts 193 | *.lnk -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | sudo: false 5 | install: false 6 | cache: 7 | directories: 8 | - $HOME/.m2/repository 9 | #after_success: 10 | # - mvn clean test -Pcoveralls jacoco:report coveralls:report -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.2.5 4 | 1. 新增:优化 Redisson 的判断逻辑,默认直接用 single 模式创建 5 | 1. 更改:更新 parent 版本为 1.3.0 6 | 2. 更改:更新 Redisson 版本为 3.7.5 7 | 8 | ## 1.2.4 9 | 1. 更改:更新 parent 版本为 1.2.3 10 | 2. 更改:更新 Spring Boot 版本为 1.5.14.RELEASE 11 | 3. 更改:更新 Redisson 版本为 3.7.2 12 | 13 | ## 1.2.3 14 | 1. 修复:当 `spring.redisson.cache-manager.enabled=false` 但 `spring.redisson.cache-manager.fallback-to-no-op-cache.enabled=true` 时的启动异常 15 | 2. 更改:更新 Redisson 版本为 3.7.1 16 | 17 | ## 1.2.2.2 18 | 1. 修复:注入 Customizer 为空的 NPE 19 | 20 | ## 1.2.2 21 | 1. 修复:配置路径不正确 22 | 1. 更改:更新 parent 版本为 1.2.2 23 | 2. 更改:Redisson Spring 的配置前缀更改为 `spring.redisson` 24 | 3. 更改:RedissonTransactionManager 默认更改为关闭 25 | 26 | ## 1.2.0 27 | 1. 更改:更新 parent 版本为 1.2.0 28 | 2. 更改:更新 Redisson 版本为 3.7.0,跟进最新的配置方法 29 | 3. 更改:Redisson 自动配置的前缀由 `spring.redisson` 更改为 `redisson` 30 | 4. 更改:整合 Redisson 与 Spring 的配置,前缀为 `redisson.spring` 31 | 5. 更改:RedissonSpringCacheManager 的默认配置,`dynamic` 由 true 改为 false,`fallbackToNoOpCache` 由 false 改为 true 32 | 6. 新增:增加 Redisson 3.7.0 版本中增加的事务功能 33 | 34 | ## 1.1.1 35 | 1. 更新 Redisson 版本为 3.6.4 36 | 2. 删除 ConfigMap 中的自动增加的 `default cache` 37 | 38 | ## 1.0.1 39 | 1. 修复不能正确注入 password 的 bug 40 | 2. 完善 Redisson 的自动配置属性 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Redisson Spring Boot Starter 2 | 3 | [![Build Status](https://img.shields.io/travis/drtrang/redisson-spring-boot/master.svg?style=flat-square)](https://www.travis-ci.org/drtrang/redisson-spring-boot) 4 | [![Maven Central](https://img.shields.io/maven-central/v/com.github.drtrang/redisson-spring-boot.svg?style=flat-square)](https://maven-badges.herokuapp.com/maven-central/com.github.drtrang/redisson-spring-boot) 5 | [![GitHub Release](https://img.shields.io/github/release/drtrang/redisson-spring-boot.svg?style=flat-square)](https://github.com/drtrang/redisson-spring-boot/releases) 6 | [![License](http://img.shields.io/badge/license-apache%202-blue.svg?style=flat-square)](http://www.apache.org/licenses/LICENSE-2.0) 7 | 8 | Redisson Spring Boot Starter 将帮助你在 Spring Boot 中使用 Redisson,仅支持 Java8。 9 | 10 | ## 依赖 11 | ```xml 12 | 13 | 14 | com.github.drtrang 15 | redisson-spring-boot-starter 16 | 1.2.5 17 | 18 | 19 | 20 | 21 | com.github.drtrang 22 | redisson-spring-boot2-starter 23 | 1.2.5 24 | 25 | ``` -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.drtrang 8 | parent 9 | 1.3.0 10 | 11 | 12 | redisson-spring-boot 13 | 1.2.5 14 | pom 15 | 16 | redisson-spring-boot 17 | Spring Boot Starter for Redisson 18 | https://github.com/drtrang/redisson-spring-boot 19 | 20 | 2017 21 | 22 | 23 | 24 | trang 25 | trang 26 | donghao.l@hotmail.com 27 | +8 28 | http://blog.trang.space 29 | 30 | 31 | 32 | 33 | 34 | The Apache Software License, Version 2.0 35 | http://www.apache.org/licenses/LICENSE-2.0 36 | repo 37 | 38 | 39 | 40 | 41 | scm:git:https://github.com/drtrang/redisson-spring-boot.git 42 | scm:git:git@github.com:drtrang/redisson-spring-boot.git 43 | https://github.com/drtrang/redisson-spring-boot 44 | HEAD 45 | 46 | 47 | 48 | github 49 | https://github.com/drtrang/redisson-spring-boot/issues 50 | 51 | 52 | 53 | redisson-spring-boot-autoconfigure 54 | redisson-spring-boot-starter 55 | 56 | 57 | 58 | 59 | 60 | com.github.drtrang 61 | redisson-spring-boot-autoconfigure 62 | ${project.version} 63 | 64 | 65 | com.github.drtrang 66 | redisson-spring-boot-starter 67 | ${project.version} 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.drtrang 8 | redisson-spring-boot 9 | 1.2.5 10 | 11 | 12 | redisson-spring-boot-autoconfigure 13 | 14 | 15 | 16 | com.github.drtrang 17 | spring-boot-autoconfigure 18 | 19 | 20 | org.slf4j 21 | slf4j-api 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-configuration-processor 26 | true 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | provided 32 | 33 | 34 | org.redisson 35 | redisson 36 | true 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/RedissonAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure; 2 | 3 | import static java.util.Collections.emptyList; 4 | import static java.util.stream.Collectors.toSet; 5 | import static org.springframework.boot.autoconfigure.condition.ConditionOutcome.match; 6 | import static org.springframework.boot.autoconfigure.condition.ConditionOutcome.noMatch; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | import org.redisson.Redisson; 13 | import org.redisson.api.RedissonClient; 14 | import org.redisson.config.Config; 15 | import org.springframework.beans.factory.ObjectProvider; 16 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 17 | import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; 18 | import org.springframework.boot.autoconfigure.condition.ConditionMessage; 19 | import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style; 20 | import org.springframework.boot.autoconfigure.condition.ConditionOutcome; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 23 | import org.springframework.boot.autoconfigure.condition.SpringBootCondition; 24 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.ConditionContext; 27 | import org.springframework.context.annotation.Conditional; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.core.type.AnnotatedTypeMetadata; 30 | 31 | import com.github.trang.autoconfigure.Customizer; 32 | import com.github.trang.redisson.autoconfigure.RedissonAutoConfiguration.RedissonCondition; 33 | import com.github.trang.redisson.autoconfigure.RedissonProperties.ClusterServersConfig; 34 | import com.github.trang.redisson.autoconfigure.RedissonProperties.MasterSlaveServersConfig; 35 | import com.github.trang.redisson.autoconfigure.RedissonProperties.ReplicatedServersConfig; 36 | import com.github.trang.redisson.autoconfigure.RedissonProperties.SentinelServersConfig; 37 | import com.github.trang.redisson.autoconfigure.RedissonProperties.SingleServerConfig; 38 | import com.github.trang.redisson.autoconfigure.enums.RedissonType; 39 | 40 | import lombok.extern.slf4j.Slf4j; 41 | 42 | /** 43 | * Redisson 自动配置 44 | * 45 | * @author trang 46 | */ 47 | @Configuration 48 | @ConditionalOnClass(Redisson.class) 49 | @Conditional(RedissonCondition.class) 50 | @AutoConfigureBefore(CacheAutoConfiguration.class) 51 | @EnableConfigurationProperties(RedissonProperties.class) 52 | @Slf4j 53 | public class RedissonAutoConfiguration { 54 | 55 | private RedissonProperties redissonProperties; 56 | private List> redissonCustomizers; 57 | 58 | public RedissonAutoConfiguration(RedissonProperties redissonProperties, 59 | ObjectProvider>> customizersProvider) { 60 | this.redissonProperties = redissonProperties; 61 | this.redissonCustomizers = customizersProvider.getIfAvailable(); 62 | this.redissonCustomizers = redissonCustomizers != null ? redissonCustomizers : emptyList(); 63 | } 64 | 65 | static class RedissonCondition extends SpringBootCondition { 66 | @Override 67 | public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { 68 | String type = context.getEnvironment().getProperty("redisson.type"); 69 | if (type == null || type.isEmpty() || type.trim().isEmpty()) { 70 | type = RedissonType.SINGLE.name(); 71 | } 72 | ConditionMessage.Builder condition = ConditionMessage.forCondition("RedissonCondition", 73 | String.format("(redisson.type=%s)", type)); 74 | if (type.equalsIgnoreCase(RedissonType.NONE.name())) { 75 | return noMatch(condition.found("matched value").items(Style.QUOTE, type)); 76 | } 77 | Set relaxedTypes = Arrays.stream(RedissonType.values()) 78 | .filter(t -> t != RedissonType.NONE) 79 | .map(Enum::name) 80 | .map(name -> Arrays.asList(name, name.toLowerCase(), name.toUpperCase())) 81 | .flatMap(List::stream) 82 | .collect(toSet()); 83 | if (relaxedTypes.contains(type)) { 84 | return match(condition.found("matched value").items(Style.QUOTE, type)); 85 | } else { 86 | return noMatch(condition.because("has unrecognized value '" + type + "'")); 87 | } 88 | } 89 | } 90 | 91 | @Bean(destroyMethod = "shutdown") 92 | @ConditionalOnMissingBean(RedissonClient.class) 93 | public RedissonClient redisson() { 94 | log.debug("redisson-client init..."); 95 | Config config = new Config(); 96 | configGlobal(config); 97 | switch (redissonProperties.getType()) { 98 | case SINGLE: 99 | configSingle(config); 100 | break; 101 | case CLUSTER: 102 | configCluster(config); 103 | break; 104 | case MASTER_SLAVE: 105 | configMasterSlave(config); 106 | break; 107 | case SENTINEL: 108 | configSentinel(config); 109 | break; 110 | case REPLICATED: 111 | configReplicated(config); 112 | break; 113 | default: 114 | throw new IllegalArgumentException("illegal redisson type: " + redissonProperties.getType()); 115 | } 116 | // 用户自定义配置,拥有最高优先级 117 | redissonCustomizers.forEach(customizer -> customizer.customize(config)); 118 | return Redisson.create(config); 119 | } 120 | 121 | private void configGlobal(Config config) { 122 | config.setCodec(redissonProperties.getCodec().getInstance()) 123 | .setThreads(redissonProperties.getThreads()) 124 | .setNettyThreads(redissonProperties.getNettyThreads()) 125 | .setExecutor(redissonProperties.getExecutor()) 126 | .setKeepPubSubOrder(redissonProperties.isKeepPubSubOrder()) 127 | .setTransportMode(redissonProperties.getTransportMode()) 128 | .setEventLoopGroup(redissonProperties.getEventLoopGroup()) 129 | .setReferenceCodecProvider(redissonProperties.getReferenceCodecProvider()) 130 | .setLockWatchdogTimeout(redissonProperties.getLockWatchdogTimeout()) 131 | .setAddressResolverGroupFactory(redissonProperties.getAddressResolverGroupFactory().getInstance()) 132 | .setReferenceEnabled(redissonProperties.isReferenceEnabled()); 133 | } 134 | 135 | private void configSingle(Config config) { 136 | SingleServerConfig properties = redissonProperties.getSingle(); 137 | config.useSingleServer() 138 | // BaseConfig 139 | .setPassword(properties.getPassword()) 140 | .setSubscriptionsPerConnection(properties.getSubscriptionsPerConnection()) 141 | .setRetryAttempts(properties.getRetryAttempts()) 142 | .setRetryInterval(properties.getRetryInterval()) 143 | .setTimeout(properties.getTimeout()) 144 | .setClientName(properties.getClientName()) 145 | .setPingTimeout(properties.getPingTimeout()) 146 | .setConnectTimeout(properties.getConnectTimeout()) 147 | .setIdleConnectionTimeout(properties.getIdleConnectionTimeout()) 148 | .setSslEnableEndpointIdentification(properties.isSslEnableEndpointIdentification()) 149 | .setSslProvider(properties.getSslProvider()) 150 | .setSslTruststore(properties.getSslTrustStore()) 151 | .setSslTruststorePassword(properties.getSslKeystorePassword()) 152 | .setSslKeystore(properties.getSslKeystore()) 153 | .setSslKeystorePassword(properties.getSslKeystorePassword()) 154 | .setPingConnectionInterval(properties.getPingConnectionInterval()) 155 | .setKeepAlive(properties.isKeepAlive()) 156 | .setTcpNoDelay(properties.isTcpNoDelay()) 157 | // SingleServerConfig 158 | .setAddress(properties.getAddress()) 159 | .setDatabase(properties.getDatabase()) 160 | .setConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize()) 161 | .setConnectionPoolSize(properties.getConnectionPoolSize()) 162 | .setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize()) 163 | .setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize()) 164 | .setDnsMonitoringInterval(properties.getDnsMonitoringInterval()); 165 | } 166 | 167 | private void configCluster(Config config) { 168 | ClusterServersConfig properties = redissonProperties.getCluster(); 169 | config.useClusterServers() 170 | // BaseConfig 171 | .setPassword(properties.getPassword()) 172 | .setSubscriptionsPerConnection(properties.getSubscriptionsPerConnection()) 173 | .setRetryAttempts(properties.getRetryAttempts()) 174 | .setRetryInterval(properties.getRetryInterval()) 175 | .setTimeout(properties.getTimeout()) 176 | .setClientName(properties.getClientName()) 177 | .setPingTimeout(properties.getPingTimeout()) 178 | .setConnectTimeout(properties.getConnectTimeout()) 179 | .setIdleConnectionTimeout(properties.getIdleConnectionTimeout()) 180 | .setSslEnableEndpointIdentification(properties.isSslEnableEndpointIdentification()) 181 | .setSslProvider(properties.getSslProvider()) 182 | .setSslTruststore(properties.getSslTrustStore()) 183 | .setSslTruststorePassword(properties.getSslKeystorePassword()) 184 | .setSslKeystore(properties.getSslKeystore()) 185 | .setSslKeystorePassword(properties.getSslKeystorePassword()) 186 | .setPingConnectionInterval(properties.getPingConnectionInterval()) 187 | .setKeepAlive(properties.isKeepAlive()) 188 | .setTcpNoDelay(properties.isTcpNoDelay()) 189 | // BaseMasterSlaveServersConfig 190 | .setLoadBalancer(properties.getLoadBalancer().getInstance()) 191 | .setMasterConnectionMinimumIdleSize(properties.getMasterConnectionMinimumIdleSize()) 192 | .setMasterConnectionPoolSize(properties.getMasterConnectionPoolSize()) 193 | .setSlaveConnectionMinimumIdleSize(properties.getSlaveConnectionMinimumIdleSize()) 194 | .setSlaveConnectionPoolSize(properties.getSlaveConnectionPoolSize()) 195 | .setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize()) 196 | .setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize()) 197 | .setFailedSlaveCheckInterval(properties.getFailedSlaveCheckInterval()) 198 | .setFailedSlaveReconnectionInterval(properties.getFailedSlaveReconnectionInterval()) 199 | .setReadMode(properties.getReadMode()) 200 | .setSubscriptionMode(properties.getSubscriptionMode()) 201 | .setDnsMonitoringInterval(properties.getDnsMonitoringInterval()) 202 | // ClusterServersConfig 203 | .addNodeAddress(properties.getNodeAddresses()) 204 | .setScanInterval(properties.getScanInterval()); 205 | } 206 | 207 | private void configMasterSlave(Config config) { 208 | MasterSlaveServersConfig properties = redissonProperties.getMasterSlave(); 209 | config.useMasterSlaveServers() 210 | // BaseConfig 211 | .setPassword(properties.getPassword()) 212 | .setSubscriptionsPerConnection(properties.getSubscriptionsPerConnection()) 213 | .setRetryAttempts(properties.getRetryAttempts()) 214 | .setRetryInterval(properties.getRetryInterval()) 215 | .setTimeout(properties.getTimeout()) 216 | .setClientName(properties.getClientName()) 217 | .setPingTimeout(properties.getPingTimeout()) 218 | .setConnectTimeout(properties.getConnectTimeout()) 219 | .setIdleConnectionTimeout(properties.getIdleConnectionTimeout()) 220 | .setSslEnableEndpointIdentification(properties.isSslEnableEndpointIdentification()) 221 | .setSslProvider(properties.getSslProvider()) 222 | .setSslTruststore(properties.getSslTrustStore()) 223 | .setSslTruststorePassword(properties.getSslKeystorePassword()) 224 | .setSslKeystore(properties.getSslKeystore()) 225 | .setSslKeystorePassword(properties.getSslKeystorePassword()) 226 | .setPingConnectionInterval(properties.getPingConnectionInterval()) 227 | .setKeepAlive(properties.isKeepAlive()) 228 | .setTcpNoDelay(properties.isTcpNoDelay()) 229 | // BaseMasterSlaveServersConfig 230 | .setLoadBalancer(properties.getLoadBalancer().getInstance()) 231 | .setMasterConnectionMinimumIdleSize(properties.getMasterConnectionMinimumIdleSize()) 232 | .setMasterConnectionPoolSize(properties.getMasterConnectionPoolSize()) 233 | .setSlaveConnectionMinimumIdleSize(properties.getSlaveConnectionMinimumIdleSize()) 234 | .setSlaveConnectionPoolSize(properties.getSlaveConnectionPoolSize()) 235 | .setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize()) 236 | .setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize()) 237 | .setFailedSlaveCheckInterval(properties.getFailedSlaveCheckInterval()) 238 | .setFailedSlaveReconnectionInterval(properties.getFailedSlaveReconnectionInterval()) 239 | .setReadMode(properties.getReadMode()) 240 | .setSubscriptionMode(properties.getSubscriptionMode()) 241 | .setDnsMonitoringInterval(properties.getDnsMonitoringInterval()) 242 | // MasterSlaveServersConfig 243 | .setMasterAddress(properties.getMasterAddress()) 244 | .addSlaveAddress(properties.getSlaveAddresses()) 245 | .setDatabase(properties.getDatabase()); 246 | } 247 | 248 | private void configSentinel(Config config) { 249 | SentinelServersConfig properties = redissonProperties.getSentinel(); 250 | config.useSentinelServers() 251 | // BaseConfig 252 | .setPassword(properties.getPassword()) 253 | .setSubscriptionsPerConnection(properties.getSubscriptionsPerConnection()) 254 | .setRetryAttempts(properties.getRetryAttempts()) 255 | .setRetryInterval(properties.getRetryInterval()) 256 | .setTimeout(properties.getTimeout()) 257 | .setClientName(properties.getClientName()) 258 | .setPingTimeout(properties.getPingTimeout()) 259 | .setConnectTimeout(properties.getConnectTimeout()) 260 | .setIdleConnectionTimeout(properties.getIdleConnectionTimeout()) 261 | .setSslEnableEndpointIdentification(properties.isSslEnableEndpointIdentification()) 262 | .setSslProvider(properties.getSslProvider()) 263 | .setSslTruststore(properties.getSslTrustStore()) 264 | .setSslTruststorePassword(properties.getSslKeystorePassword()) 265 | .setSslKeystore(properties.getSslKeystore()) 266 | .setSslKeystorePassword(properties.getSslKeystorePassword()) 267 | .setPingConnectionInterval(properties.getPingConnectionInterval()) 268 | .setKeepAlive(properties.isKeepAlive()) 269 | .setTcpNoDelay(properties.isTcpNoDelay()) 270 | // BaseMasterSlaveServersConfig 271 | .setLoadBalancer(properties.getLoadBalancer().getInstance()) 272 | .setMasterConnectionMinimumIdleSize(properties.getMasterConnectionMinimumIdleSize()) 273 | .setMasterConnectionPoolSize(properties.getMasterConnectionPoolSize()) 274 | .setSlaveConnectionMinimumIdleSize(properties.getSlaveConnectionMinimumIdleSize()) 275 | .setSlaveConnectionPoolSize(properties.getSlaveConnectionPoolSize()) 276 | .setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize()) 277 | .setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize()) 278 | .setFailedSlaveCheckInterval(properties.getFailedSlaveCheckInterval()) 279 | .setFailedSlaveReconnectionInterval(properties.getFailedSlaveReconnectionInterval()) 280 | .setReadMode(properties.getReadMode()) 281 | .setSubscriptionMode(properties.getSubscriptionMode()) 282 | .setDnsMonitoringInterval(properties.getDnsMonitoringInterval()) 283 | // SentinelServersConfig 284 | .addSentinelAddress(properties.getSentinelAddresses()) 285 | .setMasterName(properties.getMasterName()) 286 | .setScanInterval(properties.getScanInterval()) 287 | .setDatabase(properties.getDatabase()); 288 | } 289 | 290 | private void configReplicated(Config config) { 291 | ReplicatedServersConfig properties = redissonProperties.getReplicated(); 292 | config.useReplicatedServers() 293 | // BaseConfig 294 | .setPassword(properties.getPassword()) 295 | .setSubscriptionsPerConnection(properties.getSubscriptionsPerConnection()) 296 | .setRetryAttempts(properties.getRetryAttempts()) 297 | .setRetryInterval(properties.getRetryInterval()) 298 | .setTimeout(properties.getTimeout()) 299 | .setClientName(properties.getClientName()) 300 | .setPingTimeout(properties.getPingTimeout()) 301 | .setConnectTimeout(properties.getConnectTimeout()) 302 | .setIdleConnectionTimeout(properties.getIdleConnectionTimeout()) 303 | .setSslEnableEndpointIdentification(properties.isSslEnableEndpointIdentification()) 304 | .setSslProvider(properties.getSslProvider()) 305 | .setSslTruststore(properties.getSslTrustStore()) 306 | .setSslTruststorePassword(properties.getSslKeystorePassword()) 307 | .setSslKeystore(properties.getSslKeystore()) 308 | .setSslKeystorePassword(properties.getSslKeystorePassword()) 309 | .setPingConnectionInterval(properties.getPingConnectionInterval()) 310 | .setKeepAlive(properties.isKeepAlive()) 311 | .setTcpNoDelay(properties.isTcpNoDelay()) 312 | // BaseMasterSlaveServersConfig 313 | .setLoadBalancer(properties.getLoadBalancer().getInstance()) 314 | .setMasterConnectionMinimumIdleSize(properties.getMasterConnectionMinimumIdleSize()) 315 | .setMasterConnectionPoolSize(properties.getMasterConnectionPoolSize()) 316 | .setSlaveConnectionMinimumIdleSize(properties.getSlaveConnectionMinimumIdleSize()) 317 | .setSlaveConnectionPoolSize(properties.getSlaveConnectionPoolSize()) 318 | .setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize()) 319 | .setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize()) 320 | .setFailedSlaveCheckInterval(properties.getFailedSlaveCheckInterval()) 321 | .setFailedSlaveReconnectionInterval(properties.getFailedSlaveReconnectionInterval()) 322 | .setReadMode(properties.getReadMode()) 323 | .setSubscriptionMode(properties.getSubscriptionMode()) 324 | .setDnsMonitoringInterval(properties.getDnsMonitoringInterval()) 325 | // ReplicatedServersConfig 326 | .addNodeAddress(properties.getNodeAddresses()) 327 | .setScanInterval(properties.getScanInterval()) 328 | .setDatabase(properties.getDatabase()); 329 | } 330 | 331 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/RedissonProperties.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure; 2 | 3 | import java.net.URI; 4 | import java.util.concurrent.ExecutorService; 5 | 6 | import org.redisson.codec.DefaultReferenceCodecProvider; 7 | import org.redisson.codec.ReferenceCodecProvider; 8 | import org.redisson.config.ReadMode; 9 | import org.redisson.config.SslProvider; 10 | import org.redisson.config.SubscriptionMode; 11 | import org.redisson.config.TransportMode; 12 | import org.springframework.boot.context.properties.ConfigurationProperties; 13 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 14 | 15 | import com.github.trang.redisson.autoconfigure.enums.AddressResolverGroupFactoryType; 16 | import com.github.trang.redisson.autoconfigure.enums.CodecType; 17 | import com.github.trang.redisson.autoconfigure.enums.LoadBalancerType; 18 | import com.github.trang.redisson.autoconfigure.enums.RedissonType; 19 | 20 | import io.netty.channel.EventLoopGroup; 21 | import lombok.Getter; 22 | import lombok.Setter; 23 | 24 | /** 25 | * Redisson 自动配置属性 26 | * 27 | * @author trang 28 | */ 29 | @ConfigurationProperties(prefix = "redisson") 30 | @Getter 31 | @Setter 32 | public class RedissonProperties { 33 | 34 | /** 线程池数量,默认值:当前处理核数量*2 */ 35 | private int threads = 0; 36 | /** Netty 线程池数量,默认值:当前处理核数量*2 */ 37 | private int nettyThreads = 0; 38 | /** Redis 进行序列化和反序列化的类型,默认值:jackson */ 39 | private CodecType codec = CodecType.JACKSON; 40 | /** Codec 注册和获取功能的提供者,默认值:DefaultReferenceCodecProvider */ 41 | private ReferenceCodecProvider referenceCodecProvider = new DefaultReferenceCodecProvider(); 42 | /** 单独提供一个线程池实例 */ 43 | private ExecutorService executor; 44 | /** Redisson 参考功能的配置选项,默认值:true */ 45 | private boolean referenceEnabled = true; 46 | /** TransportMode,默认值:NIO */ 47 | private TransportMode transportMode = TransportMode.NIO; 48 | /** 单独指定一个 EventLoopGroup */ 49 | private EventLoopGroup eventLoopGroup; 50 | /** 锁监视器的超时时间,默认值:30000 ms */ 51 | private long lockWatchdogTimeout = 30 * 1000; 52 | /** 是否顺序处理或并发处理 PubSub 消息,默认值:true */ 53 | private boolean keepPubSubOrder = true; 54 | /** Redis 服务端模式,默认值:single */ 55 | private RedissonType type = RedissonType.SINGLE; 56 | /** 地址解析器,默认值:DnsAddressResolverGroupFactory */ 57 | private AddressResolverGroupFactoryType addressResolverGroupFactory = AddressResolverGroupFactoryType.DEFAULT; 58 | 59 | /** 单节点模式 */ 60 | @NestedConfigurationProperty 61 | private SingleServerConfig single = new SingleServerConfig(); 62 | /** 集群模式 */ 63 | @NestedConfigurationProperty 64 | private ClusterServersConfig cluster = new ClusterServersConfig(); 65 | /** 主从模式 */ 66 | @NestedConfigurationProperty 67 | private MasterSlaveServersConfig masterSlave = new MasterSlaveServersConfig(); 68 | /** 哨兵模式 */ 69 | @NestedConfigurationProperty 70 | private SentinelServersConfig sentinel = new SentinelServersConfig(); 71 | /** 云托管模式 */ 72 | @NestedConfigurationProperty 73 | private ReplicatedServersConfig replicated = new ReplicatedServersConfig(); 74 | 75 | @Getter 76 | @Setter 77 | private static class BaseConfig { 78 | /** 连接空闲超时时间,默认值:10000 ms */ 79 | private int idleConnectionTimeout = 10000; 80 | /** PING 操作的超时时间,默认值:1000 ms */ 81 | private int pingTimeout = 1000; 82 | /** 连接超时时间,默认值:10000 ms */ 83 | private int connectTimeout = 10000; 84 | /** 命令等待超时时间,,默认值:3000 ms */ 85 | private int timeout = 3000; 86 | /** 命令失败重试次数,默认值:3 */ 87 | private int retryAttempts = 3; 88 | /** 命令重试发送时间间隔,默认值:1500 ms */ 89 | private int retryInterval = 1500; 90 | /** Redis 实例密码,默认值:null */ 91 | private String password = null; 92 | /** 单个连接最大订阅数量,默认值:5 */ 93 | private int subscriptionsPerConnection = 5; 94 | /** 客户端名称,默认值:null */ 95 | private String clientName = null; 96 | /** 启用 SSL 终端识别,默认值:true */ 97 | private boolean sslEnableEndpointIdentification = true; 98 | /** SSL 实现方式,默认值:jdk */ 99 | private SslProvider sslProvider = SslProvider.JDK; 100 | /** SSL 信任证书库路径,默认值:null */ 101 | private URI sslTrustStore = null; 102 | /** SSL 信任证书库密码,默认值:null */ 103 | private String sslTrustStorePassword = null; 104 | /** SSL 钥匙库路径,默认值:null */ 105 | private URI sslKeystore = null; 106 | /** SSL 钥匙库密码,默认值:null */ 107 | private String sslKeystorePassword = null; 108 | /** PING 命令的发送时间间隔,默认值:0 ms */ 109 | private int pingConnectionInterval = 0; 110 | /** 开启连接的 TCP KeepAlive 特性,默认值:false */ 111 | private boolean keepAlive = false; 112 | /** 开启连接的 TCP NoDelay 特性,默认值:false */ 113 | private boolean tcpNoDelay = false; 114 | } 115 | 116 | @Getter 117 | @Setter 118 | private static class BaseMasterSlaveServersConfig extends BaseConfig { 119 | /** 负载均衡算法,默认值:round_robin */ 120 | private LoadBalancerType loadBalancer = LoadBalancerType.ROUND_ROBIN; 121 | /** 主节点最小空闲连接数,默认值:32 */ 122 | private int masterConnectionMinimumIdleSize = 32; 123 | /** 主节点连接池大小,默认值:64 */ 124 | private int masterConnectionPoolSize = 64; 125 | /** 从节点最小空闲连接数,默认值:32 */ 126 | private int slaveConnectionMinimumIdleSize = 32; 127 | /** 从节点连接池大小,默认值:64 */ 128 | private int slaveConnectionPoolSize = 64; 129 | /** 当第一个 Redis 命令执行失败的时间间隔到达该值时,从节点将被排除在可用节点的内部列表中,默认值:60000 ms */ 130 | private int failedSlaveCheckInterval = 60000; 131 | /** 当节点被排除在可用服务器的内部列表中时,从节点重新连接尝试的间隔,默认值:3000 ms */ 132 | private int failedSlaveReconnectionInterval = 3000; 133 | /** 读取操作的负载均衡模式,默认值:slave */ 134 | private ReadMode readMode = ReadMode.SLAVE; 135 | /** 订阅操作的负载均衡模式,默认值:master */ 136 | private SubscriptionMode subscriptionMode = SubscriptionMode.MASTER; 137 | /** 从节点发布和订阅连接的最小空闲连接数,默认值:1 */ 138 | private int subscriptionConnectionMinimumIdleSize = 1; 139 | /** 从节点发布和订阅连接池大小,默认值:50 */ 140 | private int subscriptionConnectionPoolSize = 50; 141 | /** DNS 监测时间间隔,默认值:5000 ms */ 142 | private long dnsMonitoringInterval = 5000; 143 | } 144 | 145 | @Getter 146 | @Setter 147 | public static class SingleServerConfig extends BaseConfig { 148 | /** 节点地址,格式:redis://host:port */ 149 | private String address = "redis://127.0.0.1:6379"; 150 | /** 数据库编号,默认值:0 */ 151 | private int database = 0; 152 | /** 最小空闲连接数,默认值:32 */ 153 | private int connectionMinimumIdleSize = 32; 154 | /** 连接池大小,默认值:64 */ 155 | private int connectionPoolSize = 64; 156 | /** 发布和订阅连接的最小空闲连接数,默认值:1 */ 157 | private int subscriptionConnectionMinimumIdleSize = 1; 158 | /** 发布和订阅连接池大小,默认值:50 */ 159 | private int subscriptionConnectionPoolSize = 50; 160 | /** DNS 监测时间间隔,默认值:5000 ms */ 161 | private long dnsMonitoringInterval = 5000L; 162 | } 163 | 164 | @Getter 165 | @Setter 166 | public static class ClusterServersConfig extends BaseMasterSlaveServersConfig { 167 | /** 集群节点地址,格式:redis://host:port */ 168 | private String[] nodeAddresses; 169 | /** 集群扫描间隔时间,默认值:1000 ms */ 170 | private int scanInterval = 1000; 171 | } 172 | 173 | @Getter 174 | @Setter 175 | public static class MasterSlaveServersConfig extends BaseMasterSlaveServersConfig { 176 | /** 主节点地址,格式:redis://host:port */ 177 | private String masterAddress; 178 | /** 从节点地址,格式:redis://host:port */ 179 | private String[] slaveAddresses; 180 | /** 数据库编号,默认值:0 */ 181 | private int database = 0; 182 | } 183 | 184 | @Getter 185 | @Setter 186 | public static class SentinelServersConfig extends BaseMasterSlaveServersConfig { 187 | /** 哨兵节点地址,格式:redis://host:port */ 188 | private String[] sentinelAddresses; 189 | /** 主服务器的名称,默认值:null */ 190 | private String masterName = null; 191 | /** 哨兵扫描间隔时间,默认值:1000 ms */ 192 | private int scanInterval = 1000; 193 | /** 数据库编号,默认值:0 */ 194 | private int database = 0; 195 | } 196 | 197 | @Getter 198 | @Setter 199 | public static class ReplicatedServersConfig extends BaseMasterSlaveServersConfig { 200 | /** 集群节点地址,格式:redis://host:port */ 201 | private String[] nodeAddresses; 202 | /** 主节点变化扫描间隔时间,默认值:1000 ms */ 203 | private int scanInterval = 1000; 204 | /** 数据库编号,默认值:0 */ 205 | private int database = 0; 206 | } 207 | 208 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/RedissonSpringAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure; 2 | 3 | import static java.util.Collections.emptyList; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.redisson.Redisson; 9 | import org.redisson.api.RedissonClient; 10 | import org.redisson.spring.cache.CacheConfig; 11 | import org.redisson.spring.cache.RedissonSpringCacheManager; 12 | import org.redisson.spring.transaction.RedissonTransactionManager; 13 | import org.springframework.beans.factory.ObjectProvider; 14 | import org.springframework.beans.factory.config.BeanDefinition; 15 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; 16 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 17 | import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; 18 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 22 | import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; 23 | import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; 24 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 25 | import org.springframework.cache.CacheManager; 26 | import org.springframework.cache.interceptor.CacheAspectSupport; 27 | import org.springframework.cache.support.CompositeCacheManager; 28 | import org.springframework.context.annotation.Bean; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.context.annotation.Primary; 31 | 32 | import com.github.trang.autoconfigure.Customizer; 33 | import com.github.trang.redisson.autoconfigure.RedissonSpringProperties.RedissonCacheManagerProperties; 34 | 35 | import lombok.extern.slf4j.Slf4j; 36 | 37 | /** 38 | * Redisson Spring 自动配置 39 | * 40 | * @author trang 41 | */ 42 | @Configuration 43 | @ConditionalOnClass(Redisson.class) 44 | @ConditionalOnBean(RedissonClient.class) 45 | @AutoConfigureAfter({CacheAutoConfiguration.class, TransactionAutoConfiguration.class}) 46 | @EnableConfigurationProperties(RedissonSpringProperties.class) 47 | @Slf4j 48 | public class RedissonSpringAutoConfiguration { 49 | 50 | private RedissonSpringProperties redissonSpringProperties; 51 | private List> redissonSpringCacheManagerCustomizers; 52 | 53 | public RedissonSpringAutoConfiguration(RedissonSpringProperties redissonSpringProperties, 54 | ObjectProvider>> customizersProvider) { 55 | this.redissonSpringProperties = redissonSpringProperties; 56 | this.redissonSpringCacheManagerCustomizers = customizersProvider.getIfAvailable(); 57 | this.redissonSpringCacheManagerCustomizers = redissonSpringCacheManagerCustomizers != null 58 | ? redissonSpringCacheManagerCustomizers : emptyList(); 59 | } 60 | 61 | /** 62 | * 声明 RedissonSpringCacheManager 63 | * 64 | * 由于 #{@link CacheAutoConfiguration} 的加载顺序在本类之前,并且其默认会注册一个 #{@link org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration}, 65 | * 所以这里将 beanName 设置为 'cacheManager',目的是为了覆盖掉默认的 cacheManager(Spring 有一种机制来保证 bean 的优先级,详情请查看 66 | * #{@link DefaultListableBeanFactory#registerBeanDefinition(String, BeanDefinition)}) 67 | * 68 | * 为什么不先加载本类呢?因为 CacheAutoConfiguration 中有一些功能是我们需要的,如果先加载本类,那么 RedissonSpringCacheManager注册成功后, 69 | * CacheAutoConfiguration 将不会加载,因为其加载条件是不存在 CacheManager 70 | * 71 | * @param redisson redisson 客户端 72 | * @return RedissonSpringCacheManager cacheManager 73 | */ 74 | @Bean 75 | @ConditionalOnClass(CacheManager.class) 76 | @ConditionalOnBean(CacheAspectSupport.class) 77 | @ConditionalOnMissingBean(RedissonSpringCacheManager.class) 78 | @ConditionalOnProperty(prefix = "spring.redisson.cache-manager", name = "enabled", havingValue = "true", matchIfMissing = true) 79 | public RedissonSpringCacheManager cacheManager(RedissonClient redisson) { 80 | log.info("redisson cache-manager init..."); 81 | RedissonCacheManagerProperties redissonCacheManagerProperties = redissonSpringProperties.getCacheManager(); 82 | // 获取 ConfigMap 83 | // CacheConfig: 84 | // ttl 过期时间,key 写入一定时间后删除,相当于 GuavaCache 的 expireAfterWrite 85 | // maxIdleTime 最大空闲时间,key 一定时间内没有被访问后删除,相当于 GuavaCache 的 expireAfterAccess 86 | // maxIdleTime 最大数量,达到一定数量后删除一部分 key,基于 LRU 算法 87 | Map config = redissonCacheManagerProperties.getConfigs(); 88 | // 创建 CacheManager,ConfigMap 会转换为 Cache 89 | RedissonSpringCacheManager redissonSpringCacheManager = new RedissonSpringCacheManager(redisson, config); 90 | // RedissonSpringCacheManager 中的 dynamic 属性默认为 true,即获取不存在的 Cache 时,Redisson 创建一个永不过期的 Cache 以供使用 91 | // 个人认为这样不合理,会导致滥用缓存,所以 starter 中 dynamic 的默认值为 false,当获取不存在的 Cache 时会抛出异常 92 | // 当然,你也可以手动开启 dynamic 功能 93 | if (!redissonCacheManagerProperties.isDynamic()) { 94 | redissonSpringCacheManager.setCacheNames(redissonCacheManagerProperties.getConfigs().keySet()); 95 | } 96 | if (redissonCacheManagerProperties.getCodec() != null) { 97 | redissonSpringCacheManager.setCodec(redissonCacheManagerProperties.getCodec().getInstance()); 98 | } 99 | if (redissonCacheManagerProperties.getConfigLocation() != null && !redissonCacheManagerProperties.getConfigLocation().isEmpty()) { 100 | redissonSpringCacheManager.setConfigLocation(redissonCacheManagerProperties.getConfigLocation()); 101 | } 102 | redissonSpringCacheManager.setAllowNullValues(redissonCacheManagerProperties.isAllowNullValues()); 103 | // 用户自定义配置,拥有最高优先级 104 | redissonSpringCacheManagerCustomizers.forEach(customizer -> customizer.customize(redissonSpringCacheManager)); 105 | return redissonSpringCacheManager; 106 | } 107 | 108 | /** 109 | * 声明 CompositeCacheManager 110 | * 111 | * 1. 因为上面已经有 RedissonSpringCacheManager 了,所以这里有 @Primary 修饰 112 | * 2. 注入 RedissonSpringCacheManager 而不是 CacheManager 是因为该方法只为 RedissonSpringCacheManager 服务 :) 113 | * 3. 当声明 RedissonSpringCacheManager 的 beanName 为 'cacheManager' 时,@ConditionalOnBean 的条件 114 | * 'value=RedissonSpringCacheManager.class' 并不能生效,但是别的 beanName 是没问题的,具体原因待查。 115 | * 另外根据实验得出 spring-boot 1.x 中各条件之间是或的关系,而 spring boot 2.x 中是且的关系。 116 | * 117 | * @return CompositeCacheManager cacheManager 118 | */ 119 | @Bean 120 | @Primary 121 | @ConditionalOnBean(name = "cacheManager") 122 | @ConditionalOnMissingBean(CompositeCacheManager.class) 123 | @ConditionalOnProperty(prefix = "spring.redisson.cache-manager", name = {"enabled", "fallback-to-no-op-cache"}, 124 | havingValue = "true", matchIfMissing = true) 125 | public CompositeCacheManager compositeCacheManager(RedissonSpringCacheManager cacheManager) { 126 | log.info("composite cache-manager init..."); 127 | CompositeCacheManager compositeCacheManager = new CompositeCacheManager(cacheManager); 128 | // 设置 NoOpCacheManager,当获取不存在的 Cache 时不会抛出异常,而是穿透缓存 129 | compositeCacheManager.setFallbackToNoOpCache(true); 130 | return compositeCacheManager; 131 | } 132 | 133 | /** 134 | * 声明 RedissonTransactionManager 135 | * 136 | * 加载顺序放到了 #{@link TransactionAutoConfiguration} 之后,避免影响 137 | * #{@link DataSourceTransactionManagerAutoConfiguration.DataSourceTransactionManagerConfiguration} 的加载 138 | * 139 | * @param redisson redisson 客户端 140 | * @return RedissonTransactionManager redissonTransactionManager 141 | */ 142 | @Bean 143 | @ConditionalOnMissingBean(RedissonTransactionManager.class) 144 | @ConditionalOnClass(name = "org.springframework.transaction.PlatformTransactionManager") 145 | @ConditionalOnProperty(prefix = "spring.redisson.transaction", name = "enabled", havingValue = "true") 146 | public RedissonTransactionManager redissonTransactionManager(RedissonClient redisson) { 147 | return new RedissonTransactionManager(redisson); 148 | } 149 | 150 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/RedissonSpringProperties.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.redisson.spring.cache.CacheConfig; 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.boot.context.properties.NestedConfigurationProperty; 9 | 10 | import com.github.trang.redisson.autoconfigure.enums.CodecType; 11 | 12 | import lombok.Getter; 13 | import lombok.Setter; 14 | 15 | /** 16 | * Redisson Spring 自动配置属性 17 | * 18 | * @author trang 19 | */ 20 | @ConfigurationProperties(prefix = "spring.redisson") 21 | @Getter 22 | @Setter 23 | public class RedissonSpringProperties { 24 | 25 | /** Redisson CacheManager 配置 */ 26 | @NestedConfigurationProperty 27 | private RedissonCacheManagerProperties cacheManager = new RedissonCacheManagerProperties(); 28 | 29 | /** Redisson TransactionManager 配置 */ 30 | @NestedConfigurationProperty 31 | private RedissonTransactionManagerProperties transaction = new RedissonTransactionManagerProperties(); 32 | 33 | @Getter 34 | @Setter 35 | public static class RedissonCacheManagerProperties { 36 | /** 是否开启 RedissonSpringCacheManager,默认值:true */ 37 | private boolean enabled = true; 38 | /** 是否缓存 null 值,默认值:true */ 39 | private boolean allowNullValues = true; 40 | /** 序列化类型 */ 41 | private CodecType codec; 42 | /** RedissonCache 配置 */ 43 | private Map configs = new HashMap<>(); 44 | /** 是否开启动态缓存,默认值:false */ 45 | private boolean dynamic = false; 46 | /** 缓存配置路径 */ 47 | private String configLocation; 48 | /** 是否回滚到 NoOpCacheManager,默认值:true */ 49 | private boolean fallbackToNoOpCache = true; 50 | } 51 | 52 | @Getter 53 | @Setter 54 | public static class RedissonTransactionManagerProperties { 55 | /** 是否开启 RedissonTransactionManager,默认值:false */ 56 | private boolean enabled = false; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/enums/AddressResolverGroupFactoryType.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure.enums; 2 | 3 | import org.redisson.connection.AddressResolverGroupFactory; 4 | import org.redisson.connection.DnsAddressResolverGroupFactory; 5 | import org.redisson.connection.RoundRobinDnsAddressResolverGroupFactory; 6 | 7 | /** 8 | * AddressResolverGroupFactoryType 9 | * 10 | * @author trang 11 | */ 12 | public enum AddressResolverGroupFactoryType { 13 | 14 | /** 15 | * 默认 16 | */ 17 | DEFAULT { 18 | @Override 19 | public AddressResolverGroupFactory getInstance() { 20 | return new DnsAddressResolverGroupFactory(); 21 | } 22 | }, 23 | 24 | /** 25 | * 轮询 26 | */ 27 | ROUND_ROBIN { 28 | @Override 29 | public AddressResolverGroupFactory getInstance() { 30 | return new RoundRobinDnsAddressResolverGroupFactory(); 31 | } 32 | }; 33 | 34 | public abstract AddressResolverGroupFactory getInstance(); 35 | 36 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/enums/CodecType.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure.enums; 2 | 3 | import org.redisson.client.codec.ByteArrayCodec; 4 | import org.redisson.client.codec.Codec; 5 | import org.redisson.client.codec.StringCodec; 6 | import org.redisson.codec.CborJacksonCodec; 7 | import org.redisson.codec.FstCodec; 8 | import org.redisson.codec.JsonJacksonCodec; 9 | import org.redisson.codec.KryoCodec; 10 | import org.redisson.codec.LZ4Codec; 11 | import org.redisson.codec.MsgPackJacksonCodec; 12 | import org.redisson.codec.SerializationCodec; 13 | import org.redisson.codec.SmileJacksonCodec; 14 | import org.redisson.codec.SnappyCodec; 15 | 16 | /** 17 | * 序列化方式 18 | * 19 | * @author trang 20 | */ 21 | public enum CodecType { 22 | 23 | /** 24 | * Jackson JSON 编码 默认编码 25 | */ 26 | JACKSON { 27 | @Override 28 | public Codec getInstance() { 29 | return new JsonJacksonCodec(); 30 | } 31 | }, 32 | 33 | /** 34 | * 另一个进制的 JSON 编码 35 | */ 36 | SMILE { 37 | @Override 38 | public Codec getInstance() { 39 | return new SmileJacksonCodec(); 40 | } 41 | }, 42 | 43 | /** 44 | * 又一个二进制的 JSON 编码 45 | */ 46 | CBOR { 47 | @Override 48 | public Codec getInstance() { 49 | return new CborJacksonCodec(); 50 | } 51 | }, 52 | 53 | /** 54 | * 再来一个二进制的 JSON 编码 55 | */ 56 | MSG_PACK { 57 | @Override 58 | public Codec getInstance() { 59 | return new MsgPackJacksonCodec(); 60 | } 61 | }, 62 | 63 | /** 64 | * Kryo 二进制对象序列化编码 65 | */ 66 | KRYO { 67 | @Override 68 | public Codec getInstance() { 69 | return new KryoCodec(); 70 | } 71 | }, 72 | 73 | /** 74 | * JDK 序列化编码 75 | */ 76 | JDK { 77 | @Override 78 | public Codec getInstance() { 79 | return new SerializationCodec(); 80 | } 81 | }, 82 | 83 | /** 84 | * Fst 二进制对象序列化编码 85 | */ 86 | FST { 87 | @Override 88 | public Codec getInstance() { 89 | return new FstCodec(); 90 | } 91 | }, 92 | 93 | /** 94 | * 压缩型序列化对象编码 95 | */ 96 | LZ4 { 97 | @Override 98 | public Codec getInstance() { 99 | return new LZ4Codec(); 100 | } 101 | }, 102 | 103 | /** 104 | * 另一个压缩型序列化对象编码 105 | */ 106 | SNAPPY { 107 | @Override 108 | public Codec getInstance() { 109 | return new SnappyCodec(); 110 | } 111 | }, 112 | 113 | /** 114 | * 纯字符串编码(无转换) 115 | */ 116 | STRING { 117 | @Override 118 | public Codec getInstance() { 119 | return new StringCodec(); 120 | } 121 | }, 122 | 123 | /** 124 | * 字节数组编码 125 | */ 126 | BYTE_ARRAY { 127 | @Override 128 | public Codec getInstance() { 129 | return new ByteArrayCodec(); 130 | } 131 | }; 132 | 133 | public abstract Codec getInstance(); 134 | 135 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/enums/LoadBalancerType.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure.enums; 2 | 3 | import org.redisson.connection.balancer.LoadBalancer; 4 | import org.redisson.connection.balancer.RandomLoadBalancer; 5 | import org.redisson.connection.balancer.RoundRobinLoadBalancer; 6 | 7 | /** 8 | * 负载均衡算法 9 | * 10 | * @author trang 11 | */ 12 | public enum LoadBalancerType { 13 | 14 | /** 15 | * 轮询 16 | */ 17 | ROUND_ROBIN { 18 | @Override 19 | public LoadBalancer getInstance() { 20 | return new RoundRobinLoadBalancer(); 21 | } 22 | }, 23 | 24 | /** 25 | * 加权轮询,这里不提供该方式,因为构造 WeightedRoundRobinBalancer 实例时需要传入权重参数,如有需要请创建 #{@code Customizer} 26 | */ 27 | WEIGHTED_ROUND_ROBIN { 28 | @Override 29 | public LoadBalancer getInstance() { 30 | throw new UnsupportedOperationException("please create a Customizer."); 31 | } 32 | }, 33 | 34 | /** 35 | * 随机 36 | */ 37 | RANDOM { 38 | @Override 39 | public LoadBalancer getInstance() { 40 | return new RandomLoadBalancer(); 41 | } 42 | }; 43 | 44 | public abstract LoadBalancer getInstance(); 45 | 46 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/java/com/github/trang/redisson/autoconfigure/enums/RedissonType.java: -------------------------------------------------------------------------------- 1 | package com.github.trang.redisson.autoconfigure.enums; 2 | 3 | /** 4 | * Redis 服务端模式 5 | * 6 | * @author trang 7 | */ 8 | public enum RedissonType { 9 | 10 | /** 11 | * 单节点模式 12 | */ 13 | SINGLE, 14 | 15 | /** 16 | * 集群模式 17 | */ 18 | CLUSTER, 19 | 20 | /** 21 | * 主从模式 22 | */ 23 | MASTER_SLAVE, 24 | 25 | /** 26 | * 哨兵模式 27 | */ 28 | SENTINEL, 29 | 30 | /** 31 | * 云托管模式 32 | */ 33 | REPLICATED, 34 | 35 | /** 36 | * 禁用 Redisson 37 | */ 38 | NONE 39 | 40 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "hints": [ 3 | { 4 | "name": "redisson.reference-codec-provider", 5 | "providers": [ 6 | { 7 | "name": "class-reference", 8 | "parameters": { 9 | "target": "org.redisson.codec.ReferenceCodecProvider" 10 | } 11 | } 12 | ] 13 | }, 14 | { 15 | "name": "redisson.executor", 16 | "providers": [ 17 | { 18 | "name": "class-reference", 19 | "parameters": { 20 | "target": "java.util.concurrent.ExecutorService" 21 | } 22 | } 23 | ] 24 | }, 25 | { 26 | "name": "redisson.event-loop-group", 27 | "providers": [ 28 | { 29 | "name": "class-reference", 30 | "parameters": { 31 | "target": "io.netty.channel.EventLoopGroup" 32 | } 33 | } 34 | ] 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /redisson-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.github.trang.redisson.autoconfigure.RedissonAutoConfiguration,\ 3 | com.github.trang.redisson.autoconfigure.RedissonSpringAutoConfiguration -------------------------------------------------------------------------------- /redisson-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.github.drtrang 8 | redisson-spring-boot 9 | 1.2.5 10 | 11 | 12 | redisson-spring-boot-starter 13 | 14 | 15 | 16 | com.github.drtrang 17 | redisson-spring-boot-autoconfigure 18 | 19 | 20 | org.redisson 21 | redisson 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /redisson-spring-boot-starter/src/main/resources/META-INF/spring.provides: -------------------------------------------------------------------------------- 1 | provides: redisson,redisson-spring-boot-autoconfigure,spring-boot-autoconfigure --------------------------------------------------------------------------------