├── .gitignore ├── README.md ├── pom.xml ├── springboot-aoplog ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── aoplog │ │ │ ├── SpringbootAoplogApplication.java │ │ │ └── controller │ │ │ └── AoplogTestController.java │ └── resources │ │ ├── application.yml │ │ └── logback-spring.xml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── aoplog │ └── SpringbootAoplogApplicationTests.java ├── springboot-async ├── pom.xml └── src │ └── main │ └── java │ └── cn │ └── jboost │ ├── Application.java │ └── async │ ├── annotation │ ├── AnnotationBasedAsyncTest.java │ ├── AsyncConfig.java │ └── AsyncService.java │ └── event │ ├── EventBasedAsyncTest.java │ ├── MyEvent.java │ ├── MyEventHandler.java │ ├── MyEventHandler2.java │ └── MyEventPublisher.java ├── springboot-config ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── config │ │ │ ├── MyConfig.java │ │ │ ├── MyService.java │ │ │ ├── MyService2.java │ │ │ └── SpringbootConfigApplication.java │ └── resources │ │ ├── application.properties │ │ └── spring.xml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── config │ └── SpringbootConfigApplicationTests.java ├── springboot-error ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── error │ │ │ ├── FilterConfig.java │ │ │ ├── SpringbootErrorApplication.java │ │ │ ├── controller │ │ │ └── ExceptionTestController.java │ │ │ └── util │ │ │ └── ErrorCodeEnum.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── error │ └── SpringbootErrorApplicationTests.java ├── springboot-file ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── file │ │ ├── Application.java │ │ ├── FileController.java │ │ └── FileUtil.java │ └── resources │ └── application.yaml ├── springboot-firstapp ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── firstapp │ │ │ ├── HelloController.java │ │ │ └── SpringbootFirstappApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── firstapp │ └── SpringbootFirstappApplicationTests.java ├── springboot-java ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── java │ │ │ ├── DateTimeBean.java │ │ │ ├── LocalDateTimeController.java │ │ │ ├── LocalDateTimeFormatConfig.java │ │ │ └── SpringbootJavaApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── java │ └── SpringbootJavaApplicationTests.java ├── springboot-limiter ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── limiter │ │ ├── LimiterApplication.java │ │ └── LimiterController.java │ └── resources │ └── application.yaml ├── springboot-mybatisplus ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── mybatisplus │ │ ├── App.java │ │ ├── LocalDateTimeFormatConfig.java │ │ ├── controller │ │ ├── UserController.java │ │ └── criteria │ │ │ └── UserQueryCriteria.java │ │ ├── entity │ │ └── User.java │ │ ├── mapper │ │ └── UserMapper.java │ │ └── service │ │ └── UserService.java │ └── resources │ ├── application.yml │ └── db │ ├── data-h2.sql │ └── schema-h2.sql ├── springboot-properties ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── properties │ │ │ ├── MyConfigProperties.java │ │ │ ├── MyPropertiesUtil.java │ │ │ └── SpringbootPropertiesApplication.java │ └── resources │ │ ├── application-dev.properties │ │ ├── application-dev.yml │ │ ├── application.properties │ │ ├── application.yml │ │ ├── applicationContext.xml │ │ └── my.properties │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── properties │ ├── SpringbootPropertiesApplicationTests.java │ ├── SpringbootPropertiesHandleTest.java │ └── TraditionalPropertiesHandleTest.java ├── springboot-redis-cluster ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── redis │ │ │ └── cluster │ │ │ ├── RedisClusterApplication.java │ │ │ ├── config │ │ │ └── RedisConfig.java │ │ │ ├── controller │ │ │ └── UserController.java │ │ │ ├── entity │ │ │ └── User.java │ │ │ └── service │ │ │ ├── RedisService.java │ │ │ └── UserService.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── redis │ └── cluster │ └── test │ └── RedisTest.java ├── springboot-redis-sentinel ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── redis │ │ │ └── sentinel │ │ │ ├── RedisSentinelApplication.java │ │ │ ├── config │ │ │ └── RedisConfig.java │ │ │ ├── controller │ │ │ └── UserController.java │ │ │ ├── entity │ │ │ └── User.java │ │ │ └── service │ │ │ ├── RedisService.java │ │ │ └── UserService.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── redis │ └── sentinel │ └── test │ └── RedisTest.java ├── springboot-redis ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── redis │ │ │ ├── Application.java │ │ │ ├── RedisKeyExpirationListener.java │ │ │ └── RedisListenerConfig.java │ └── resources │ │ └── application.yaml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── redis │ └── test │ └── RedisTest.java ├── springboot-security ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── security │ │ ├── Application.java │ │ ├── HelloController.java │ │ ├── JboostAuthenticationFilter.java │ │ ├── SecurityConfig.java │ │ ├── phone │ │ ├── PhoneAuthenticationProvider.java │ │ ├── PhoneAuthenticationToken.java │ │ └── PhoneUserDetailsService.java │ │ ├── username │ │ ├── CompositeUserDetailsChecker.java │ │ ├── RetryLimitAfterPasswordFailedChecker.java │ │ ├── UsernameAuthenticationProvider.java │ │ ├── UsernameAuthenticationToken.java │ │ └── UsernameUserDetailsService.java │ │ └── util │ │ ├── LoginParam.java │ │ ├── LoginType.java │ │ └── UserType.java │ └── resources │ └── application.yaml ├── springboot-simpleauth ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── simpleauth │ │ ├── SimpleAuthApplication.java │ │ ├── auth │ │ ├── AuthInterceptor.java │ │ ├── AuthUtil.java │ │ ├── JwtConstant.java │ │ ├── RedisTokenManager.java │ │ ├── SkipAuth.java │ │ └── TokenModel.java │ │ ├── config │ │ └── WebConfiguration.java │ │ ├── controller │ │ ├── TestContoller.java │ │ └── UserController.java │ │ └── util │ │ ├── ApiResponse.java │ │ └── WebUtil.java │ └── resources │ └── application.yml ├── springboot-starter ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── starter │ │ ├── MyAutoConfig.java │ │ ├── MyProperties.java │ │ └── MyService.java │ └── resources │ └── META-INF │ └── spring.factories ├── springboot-swagger ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── swagger │ │ │ ├── SpringbootSwaggerApplication.java │ │ │ └── SwaggerController.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── swagger │ └── SpringbootSwaggerApplicationTests.java ├── springboot-tkmapper ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── jboost │ │ │ └── springboot │ │ │ └── tkmapper │ │ │ ├── SpringbootTkmapperApplication.java │ │ │ ├── controller │ │ │ └── UserController.java │ │ │ ├── domain │ │ │ └── User.java │ │ │ ├── mapper │ │ │ └── UserMapper.java │ │ │ └── service │ │ │ └── UserService.java │ └── resources │ │ ├── application.yml │ │ └── schema.sql │ └── test │ └── java │ └── cn │ └── jboost │ └── springboot │ └── tkmapper │ └── SpringbootTkmapperApplicationTests.java └── springboot-usingstarter ├── pom.xml └── src ├── main ├── java │ └── cn │ │ └── jboost │ │ └── springboot │ │ └── usingstarter │ │ └── SpringbootUsingstarterApplication.java └── resources │ └── application.properties └── test └── java └── cn └── jboost └── springboot └── usingstarter └── SpringbootUsingstarterApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | ### VS Code ### 29 | .vscode/ 30 | 31 | /*/.mvn 32 | /*/target 33 | /*/HELP.md 34 | /*/mvnw 35 | /*/mvnw.cmd 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Spring Boot 相关Demo,基于2.1.5 GA版 2 | 3 | ### 相关技术分享网址: http://blog.jboost.cn 4 | 5 | ### 欢迎关注公众号,及时获取最新分享 6 | 7 | 8 | ![微信公众号](http://blog.jboost.cn/assets/qrcode-05.jpg) 9 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | 12 | 4.0.0 13 | 14 | com.jboost.springboot 15 | springboot-demos 16 | pom 17 | 1.0-SNAPSHOT 18 | 19 | springboot-simpleauth 20 | springboot-mybatisplus 21 | springboot-redis-sentinel 22 | springboot-redis-cluster 23 | springboot-limiter 24 | springboot-security 25 | springboot-file 26 | springboot-redis 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /springboot-aoplog/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-aoplog 13 | 0.0.1-SNAPSHOT 14 | springboot-aoplog 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-test 25 | test 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | 35 | cn.jboost.springboot 36 | aoplog-spring-boot-starter 37 | 1.2-SNAPSHOT 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-actuator 43 | 44 | 45 | 46 | 47 | ${project.artifactId} 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | repackage 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /springboot-aoplog/src/main/java/cn/jboost/springboot/aoplog/SpringbootAoplogApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.aoplog; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootAoplogApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootAoplogApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-aoplog/src/main/java/cn/jboost/springboot/aoplog/controller/AoplogTestController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.aoplog.controller; 2 | 3 | import cn.jboost.springboot.logging.annotation.LogInfo; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /*** 10 | * 11 | * @Author ronwxy 12 | * @Date 2019/6/27 13:51 13 | */ 14 | @RestController 15 | @RequestMapping("test") 16 | @LogInfo 17 | public class AoplogTestController { 18 | 19 | @GetMapping 20 | public String test(@RequestParam String user){ 21 | return "Hi " + user; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /springboot-aoplog/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | spring: 5 | application: 6 | name: aoplog-test 7 | 8 | logger: 9 | path: D:\logs #默认当前项目路径下的logs目录 10 | level: info # 默认info 11 | apiPackage: cn.jboost.springboot.aoplog.controller #必须配置, api接口类所在包 12 | rootPackage: cn.jboost.springboot #必须配置,项目根包,记录该包内各类通过slf4j输出的日志 13 | -------------------------------------------------------------------------------- /springboot-aoplog/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | [%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%thread] 14 | [%logger:%line] --%msg%n 15 | 16 | 17 | 18 | 19 | 20 | ${logPath}/elk/interface.log 21 | 22 | 23 | 24 | 25 | { 26 | "project": "${projectName}", 27 | "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}", 28 | "log_level": "%level", 29 | "thread": "%thread", 30 | "class_name": "%X{callingClass}", 31 | "class_method":"%X{callingMethod}", 32 | "line_number": null, 33 | "message": "%message", 34 | "stack_trace": "%exception{5}", 35 | "req_id": "%X{reqId}", 36 | "elapsed_time": "#asLong{%X{elapsedTime}}" 37 | } 38 | 39 | 40 | 41 | 42 | 43 | INFO 44 | 45 | 46 | ${logPath}/bak/interface.%d{yyyy-MM-dd}.log 47 | 30 48 | 1GB 49 | 50 | 51 | 52 | 53 | ${logPath}/elk/error.log 54 | 55 | 56 | 57 | 58 | { 59 | "project": "${projectName}", 60 | "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}", 61 | "log_level": "%level", 62 | "thread": "%thread", 63 | "class_name": "%class", 64 | "line_number": "#asLong{%line}", 65 | "message": "%message", 66 | "stack_trace": "%exception{5}", 67 | "req_id": "%X{reqId}", 68 | "elapsed_time": "#asLong{%X{elapsedTime}}" 69 | } 70 | 71 | 72 | 73 | 74 | 75 | ERROR 76 | 77 | 78 | ${logPath}/bak/error-%d{yyyy-MM-dd}.log 79 | 80 | 30 81 | 1GB 82 | 83 | 84 | 85 | 86 | ${logPath}/elk/warn.log 87 | 88 | WARN 89 | ACCEPT 90 | DENY 91 | 92 | 93 | 94 | 95 | 96 | { 97 | "project": "${projectName}", 98 | "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}", 99 | "log_level": "%level", 100 | "thread": "%thread", 101 | "class_name": "%class", 102 | "line_number": "#asLong{%line}", 103 | "message": "%message", 104 | "stack_trace": "%exception{5}", 105 | "req_id": "%X{reqId}", 106 | "elapsed_time": "#asLong{%X{elapsedTime}}" 107 | } 108 | 109 | 110 | 111 | 112 | 113 | ${logPath}/bak/warn.%d{yyyy-MM-dd}.log 114 | 30 115 | 1GB 116 | 117 | 118 | 119 | 120 | 121 | ${logPath}/elk/info.log 122 | 123 | INFO 124 | ACCEPT 125 | DENY 126 | 127 | 128 | 129 | 130 | 131 | { 132 | "project": "${projectName}", 133 | "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}", 134 | "log_level": "%level", 135 | "thread": "%thread", 136 | "class_name": "%class", 137 | "line_number": "#asLong{%line}", 138 | "message": "%message", 139 | "stack_trace": "%exception{5}", 140 | "req_id": "%X{reqId}", 141 | "elapsed_time": "#asLong{%X{elapsedTime}}" 142 | } 143 | 144 | 145 | 146 | 147 | 148 | ${logPath}/bak/info.%d{yyyy-MM-dd}.log 149 | 30 150 | 1GB 151 | 152 | 153 | 154 | 155 | ${logPath}/elk/debug.log 156 | 157 | DEBUG 158 | ACCEPT 159 | DENY 160 | 161 | 162 | 163 | 164 | 165 | { 166 | "project": "${projectName}", 167 | "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}", 168 | "log_level": "%level", 169 | "thread": "%thread", 170 | "class_name": "%class", 171 | "line_number": "#asLong{%line}", 172 | "message": "%message", 173 | "stack_trace": "%exception{5}", 174 | "req_id": "%X{reqId}", 175 | "elapsed_time": "#asLong{%X{elapsedTime}}" 176 | } 177 | 178 | 179 | 180 | 181 | 182 | ${logPath}/bak/debug.%d{yyyy-MM-dd}.log 183 | 184 | 30 185 | 1GB 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /springboot-aoplog/src/test/java/cn/jboost/springboot/aoplog/SpringbootAoplogApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.aoplog; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootAoplogApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-async/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-async 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-test 23 | 24 | 25 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/Application.java: -------------------------------------------------------------------------------- 1 | package cn.jboost; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableAsync; 6 | 7 | /*** 8 | * 9 | * @Author ronwxy 10 | * @Date 2019/7/22 17:20 11 | */ 12 | @SpringBootApplication 13 | @EnableAsync 14 | public class Application { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(Application.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/annotation/AnnotationBasedAsyncTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.annotation; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | /*** 10 | * 11 | * @Author ronwxy 12 | * @Date 2019/7/22 17:09 13 | */ 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | public class AnnotationBasedAsyncTest { 17 | 18 | @Autowired 19 | private AsyncService asyncService; 20 | 21 | @Test 22 | public void testAsync() throws InterruptedException { 23 | System.out.println("1. running in thread: " + Thread.currentThread().getName()); 24 | asyncService.asyncMethod(); 25 | 26 | Thread.sleep(3); 27 | } 28 | 29 | @Test 30 | public void testAysncWithException() throws InterruptedException { 31 | System.out.println("1. running in thread: " + Thread.currentThread().getName()); 32 | asyncService.asyncMethodWithException(); 33 | 34 | Thread.sleep(3); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/annotation/AsyncConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.annotation; 2 | 3 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.scheduling.annotation.AsyncConfigurer; 7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 8 | 9 | import java.lang.reflect.Method; 10 | import java.util.concurrent.Executor; 11 | import java.util.concurrent.ThreadPoolExecutor; 12 | 13 | /*** 14 | * 15 | * @Author ronwxy 16 | * @Date 2019/7/22 16:47 17 | */ 18 | @Configuration 19 | public class AsyncConfig implements AsyncConfigurer { 20 | 21 | 22 | @Value("${async.corePoolSize:10}") 23 | private int corePoolSize; 24 | 25 | @Value("${async.maxPoolSize:200}") 26 | private int maxPoolSize; 27 | 28 | @Value("${async.queueCapacity:2000}") 29 | private int queueCapacity; 30 | 31 | @Value("${async.keepAlive:5}") 32 | private int keepAlive; 33 | 34 | public Executor getAsyncExecutor() { 35 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 36 | executor.setCorePoolSize(corePoolSize); 37 | executor.setMaxPoolSize(maxPoolSize); 38 | executor.setQueueCapacity(queueCapacity); 39 | executor.setKeepAliveSeconds(keepAlive); 40 | executor.setThreadNamePrefix("async-"); 41 | executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 42 | executor.setDaemon(false); //以用户线程模式运行 43 | executor.initialize(); 44 | return executor; 45 | } 46 | 47 | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 48 | return new MyAsyncUncaughtExceptionHandler(); 49 | } 50 | 51 | public static class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler { 52 | 53 | public void handleUncaughtException(Throwable throwable, Method method, Object... objects) { 54 | System.out.println("catch exception when invoke " + method.getName()); 55 | throwable.printStackTrace(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/annotation/AsyncService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.annotation; 2 | 3 | import org.springframework.scheduling.annotation.Async; 4 | import org.springframework.stereotype.Service; 5 | 6 | /*** 7 | * 8 | * @Author ronwxy 9 | * @Date 2019/7/22 17:00 10 | */ 11 | @Service 12 | public class AsyncService { 13 | 14 | @Async 15 | public void asyncMethod(){ 16 | System.out.println("2. running in thread: " + Thread.currentThread().getName()); 17 | } 18 | 19 | @Async 20 | public void asyncMethodWithException() { 21 | throw new RuntimeException("exception in async method"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/event/EventBasedAsyncTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.event; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | /*** 10 | * 11 | * @Author ronwxy 12 | * @Date 2019/7/22 17:40 13 | */ 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | public class EventBasedAsyncTest { 17 | 18 | @Autowired 19 | private MyEventPublisher myEventPublisher; 20 | 21 | @Test 22 | public void testAsync() throws InterruptedException { 23 | System.out.println("1. running in thread: " + Thread.currentThread().getName()); 24 | myEventPublisher.publishEvent(new MyEvent(this,"testing event based async")); 25 | Thread.sleep(3); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/event/MyEvent.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.event; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | /*** 6 | * 事件类 7 | * @Author ronwxy 8 | * @Date 2019/7/22 17:28 9 | */ 10 | public class MyEvent extends ApplicationEvent { 11 | 12 | private String arg; 13 | 14 | public MyEvent(Object source, String arg) { 15 | super(source); 16 | this.arg = arg; 17 | } 18 | 19 | public String getArg() { 20 | return arg; 21 | } 22 | 23 | public void setArg(String arg) { 24 | this.arg = arg; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/event/MyEventHandler.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.event; 2 | 3 | import org.springframework.context.ApplicationListener; 4 | import org.springframework.scheduling.annotation.Async; 5 | import org.springframework.stereotype.Component; 6 | 7 | /*** 8 | * 事件处理类,默认是同步执行的,需要加 @Async 注解 9 | * @Author ronwxy 10 | * @Date 2019/7/22 17:30 11 | */ 12 | @Component 13 | @Async 14 | public class MyEventHandler implements ApplicationListener { 15 | 16 | public void onApplicationEvent(MyEvent event) { 17 | System.out.println("2. running in thread: " + Thread.currentThread().getName()); 18 | System.out.println("2. arg value: " + event.getArg()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/event/MyEventHandler2.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.event; 2 | 3 | import org.springframework.context.event.EventListener; 4 | import org.springframework.scheduling.annotation.Async; 5 | import org.springframework.stereotype.Component; 6 | 7 | /*** 8 | * 事件处理类,基于 @EventListener,默认是同步执行的,需要加 @Async 注解 9 | * @Author ronwxy 10 | * @Date 2019/7/22 17:56 11 | */ 12 | @Component 13 | public class MyEventHandler2 { 14 | 15 | @EventListener 16 | @Async 17 | public void handle(MyEvent event){ 18 | System.out.println("3. running in thread: " + Thread.currentThread().getName()); 19 | System.out.println("3. arg value: " + event.getArg()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /springboot-async/src/main/java/cn/jboost/async/event/MyEventPublisher.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.async.event; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.context.ApplicationEventPublisherAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /*** 9 | * 事件发布类 10 | * @Author ronwxy 11 | * @Date 2019/7/22 17:37 12 | */ 13 | @Component 14 | public class MyEventPublisher implements ApplicationEventPublisherAware { 15 | 16 | protected ApplicationEventPublisher applicationEventPublisher; 17 | 18 | public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { 19 | this.applicationEventPublisher = applicationEventPublisher; 20 | } 21 | 22 | public void publishEvent(ApplicationEvent event){ 23 | this.applicationEventPublisher.publishEvent(event); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /springboot-config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-config 13 | 1.0.0-SNAPSHOT 14 | springboot-config 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-actuator 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /springboot-config/src/main/java/cn/jboost/springboot/config/MyConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.ImportResource; 6 | 7 | /*** 8 | * @Desc Java配置类 9 | * @Author ronwxy 10 | * @Date 2019/6/11 16:04 11 | */ 12 | @Configuration 13 | @ImportResource("spring.xml") //引入基于xml的配置 14 | public class MyConfig { 15 | 16 | @Bean 17 | public MyService myService(){ 18 | return new MyService(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /springboot-config/src/main/java/cn/jboost/springboot/config/MyService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.config; 2 | 3 | /*** 4 | * @Desc 5 | * @Author ronwxy 6 | * @Date 2019/6/11 16:05 7 | */ 8 | public class MyService { 9 | 10 | public String sayHello(String name) { 11 | return "Hi from java-based config, " + name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /springboot-config/src/main/java/cn/jboost/springboot/config/MyService2.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.config; 2 | 3 | /*** 4 | * @Desc 5 | * @Author ronwxy 6 | * @Date 2019/6/11 16:13 7 | */ 8 | public class MyService2 { 9 | 10 | public String sayHello(String name) { 11 | return "Hi from xml-based config, " + name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /springboot-config/src/main/java/cn/jboost/springboot/config/SpringbootConfigApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @SpringBootApplication 11 | @RestController 12 | public class SpringbootConfigApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(SpringbootConfigApplication.class, args); 16 | } 17 | 18 | @Autowired 19 | private MyService myService; 20 | 21 | 22 | @RequestMapping("/hi") 23 | public String sayHello(@RequestParam String name){ 24 | return myService.sayHello(name); 25 | } 26 | 27 | @Autowired 28 | private MyService2 myService2; 29 | 30 | @RequestMapping("/hi2") 31 | public String sayHello2(@RequestParam String name){ 32 | return myService2.sayHello(name); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /springboot-config/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | management.endpoints.web.exposure.include= * 2 | management.endpoints.web.exposure.exclude=beans,trace 3 | management.endpoint.health.show-details=ALWAYS 4 | -------------------------------------------------------------------------------- /springboot-config/src/main/resources/spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /springboot-config/src/test/java/cn/jboost/springboot/config/SpringbootConfigApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.config; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootConfigApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-error/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-error 13 | 0.0.1-SNAPSHOT 14 | springboot-error 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | 34 | cn.jboost.springboot 35 | error-spring-boot-starter 36 | 1.2-SNAPSHOT 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /springboot-error/src/main/java/cn/jboost/springboot/error/FilterConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.error; 2 | 3 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.Ordered; 7 | 8 | import javax.servlet.*; 9 | import java.io.IOException; 10 | 11 | /*** 12 | * 13 | * @Author ronwxy 14 | * @Date 2019/7/3 13:54 15 | */ 16 | @Configuration 17 | public class FilterConfig { 18 | 19 | @Bean 20 | public FilterRegistrationBean exceptionFilter() { 21 | ExceptionFilter exceptionFilter = new ExceptionFilter(); 22 | FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); 23 | filterRegistrationBean.setFilter(exceptionFilter); 24 | filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); 25 | filterRegistrationBean.addUrlPatterns("/exception/filter"); 26 | return filterRegistrationBean; 27 | } 28 | 29 | class ExceptionFilter implements Filter { 30 | 31 | @Override 32 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 33 | throw new RuntimeException("过滤器抛出异常"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /springboot-error/src/main/java/cn/jboost/springboot/error/SpringbootErrorApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.error; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootErrorApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootErrorApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-error/src/main/java/cn/jboost/springboot/error/controller/ExceptionTestController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.error.controller; 2 | 3 | 4 | import cn.jboost.springboot.common.exception.ExceptionUtil; 5 | import cn.jboost.springboot.error.util.ErrorCodeEnum; 6 | import com.google.common.collect.Maps; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.util.Map; 12 | 13 | /*** 14 | * 15 | * @Author ronwxy 16 | * @Date 2019/7/3 13:04 17 | */ 18 | @RestController 19 | @RequestMapping("exception") 20 | public class ExceptionTestController { 21 | 22 | /** 23 | * 不catch具体异常,主动抛出一个异常交给统一异常处理 24 | * @param 25 | * @return 26 | */ 27 | @GetMapping("client") 28 | public void clientSideException(){ 29 | ExceptionUtil.rethrowClientSideException(ErrorCodeEnum.authorizer_notexist.getMsg()); 30 | } 31 | 32 | /** 33 | * catch具体异常,然后rethrow交给统一异常处理 34 | * @param 35 | * @return 36 | */ 37 | @GetMapping("server") 38 | public void serverSideException(){ 39 | try { 40 | throw new RuntimeException("运行时异常"); 41 | } catch (Exception ex) { 42 | //这里不需要打日志,会统一在异常处理里记录日志 43 | ExceptionUtil.rethrowServerSideException(ErrorCodeEnum.internal_error.getMsg(), ex); 44 | } 45 | } 46 | 47 | /** 48 | * 正常返回 49 | * @param 50 | * @return 51 | */ 52 | @GetMapping("normal") 53 | public Map normal(){ 54 | Map result = Maps.newLinkedHashMap(); 55 | result.put("name","jboost"); 56 | result.put("website","blog.jboost.cn"); 57 | result.put("wechat","jboost-ksxy"); 58 | return result; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /springboot-error/src/main/java/cn/jboost/springboot/error/util/ErrorCodeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.error.util; 2 | 3 | 4 | 5 | /*** 6 | * 7 | * @Author ronwxy 8 | * @Date 2019/7/3 13:04 9 | */ 10 | public enum ErrorCodeEnum { 11 | 12 | qrcode_existed("该公众号下已存在同名二维码"), 13 | authorizer_notexist("公众号不存在"), 14 | internal_error("抱歉,服务出错了,请稍后重试"), 15 | gotoauth_fail("跳转授权页面失败"); 16 | 17 | private String msg; 18 | 19 | private ErrorCodeEnum(String msg) { 20 | this.msg = msg; 21 | } 22 | 23 | 24 | public String getMsg() { 25 | return msg; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot-error/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /springboot-error/src/test/java/cn/jboost/springboot/error/SpringbootErrorApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.error; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootErrorApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-file/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-file 14 | 15 | 16 | 8 17 | 8 18 | 19 | 20 | 21 | 22 | cn.hutool 23 | hutool-all 24 | 5.3.5 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-actuator 40 | 41 | 42 | 43 | 44 | ${project.artifactId} 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-maven-plugin 49 | 50 | 51 | 52 | repackage 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /springboot-file/src/main/java/cn/jboost/springboot/file/Application.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.file; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @Author ronwxy 8 | * @Date 2021/1/27 15:44 9 | * @Version 1.0 10 | */ 11 | @SpringBootApplication 12 | public class Application { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(Application.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /springboot-file/src/main/java/cn/jboost/springboot/file/FileController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.file; 2 | 3 | import org.springframework.web.bind.annotation.*; 4 | import org.springframework.web.multipart.MultipartFile; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.*; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @Author ronwxy 14 | * @Date 2021/1/27 15:33 15 | * @Version 1.0 16 | */ 17 | @RestController 18 | @RequestMapping("file") 19 | public class FileController { 20 | 21 | @PostMapping(value = "upload") 22 | public Map upload(@RequestParam MultipartFile file) throws IOException { 23 | String filePath = FileUtil.fileSave("D:\\upload\\", "file", file); 24 | Map map = new HashMap<>(); 25 | map.put("filePath",filePath); 26 | return map; 27 | } 28 | 29 | @CrossOrigin 30 | @GetMapping("download") 31 | public void download(@RequestParam("path") String path, HttpServletRequest req, HttpServletResponse res) { 32 | String absolutPath = "D:\\upload\\"+ path; 33 | // 重要,需要设置此值,否则下载后打开文件会提示文件需要修复 34 | File file = new File(absolutPath); 35 | if (file.exists()) { 36 | byte[] buffer = new byte[1024]; 37 | OutputStream os; 38 | try (FileInputStream fis= new FileInputStream(file); 39 | BufferedInputStream bis = new BufferedInputStream(fis)) { 40 | os = res.getOutputStream(); 41 | int i = bis.read(buffer); 42 | while (i != -1){ 43 | os.write(buffer,0,i); 44 | i = bis.read(buffer); 45 | } 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /springboot-file/src/main/java/cn/jboost/springboot/file/FileUtil.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.file; 2 | 3 | 4 | import cn.hutool.core.util.IdUtil; 5 | import cn.hutool.core.util.StrUtil; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.util.FileCopyUtils; 9 | import org.springframework.util.ResourceUtils; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import java.io.File; 13 | import java.io.FileNotFoundException; 14 | import java.io.IOException; 15 | import java.text.DecimalFormat; 16 | 17 | public class FileUtil extends cn.hutool.core.io.FileUtil { 18 | private static final Logger log = LoggerFactory.getLogger(FileUtil.class); 19 | private static final int GB = 1073741824; 20 | private static final int MB = 1048576; 21 | private static final int KB = 1024; 22 | private static final DecimalFormat DF = new DecimalFormat("0.00"); 23 | 24 | public FileUtil() { 25 | } 26 | 27 | public static File toFile(MultipartFile multipartFile) { 28 | String fileName = multipartFile.getOriginalFilename(); 29 | String prefix = "." + getExtensionName(fileName); 30 | File file = null; 31 | 32 | try { 33 | file = File.createTempFile(IdUtil.simpleUUID(), prefix); 34 | multipartFile.transferTo(file); 35 | } catch (IOException var5) { 36 | log.error("fail to transfer multipartFile[{}] to oss", fileName, var5); 37 | } 38 | 39 | return file; 40 | } 41 | 42 | public static void deleteFile(File... files) { 43 | File[] var1 = files; 44 | int var2 = files.length; 45 | 46 | for (int var3 = 0; var3 < var2; ++var3) { 47 | File file = var1[var3]; 48 | if (file.exists()) { 49 | file.delete(); 50 | } 51 | } 52 | 53 | } 54 | 55 | public static String getExtensionName(String filename) { 56 | if (filename != null && filename.length() > 0) { 57 | int dot = filename.lastIndexOf(46); 58 | if (dot > -1 && dot < filename.length() - 1) { 59 | return filename.substring(dot + 1); 60 | } 61 | } 62 | 63 | return filename; 64 | } 65 | 66 | public static String getFileNameNoEx(String filename) { 67 | if (filename != null && filename.length() > 0) { 68 | int dot = filename.lastIndexOf(46); 69 | if (dot > -1 && dot < filename.length()) { 70 | return filename.substring(0, dot); 71 | } 72 | } 73 | 74 | return filename; 75 | } 76 | 77 | public static String getSize(int size) { 78 | String resultSize = ""; 79 | if (size / 1073741824 >= 1) { 80 | resultSize = DF.format((double) ((float) size / 1.07374182E9F)) + "GB "; 81 | } else if (size / 1048576 >= 1) { 82 | resultSize = DF.format((double) ((float) size / 1048576.0F)) + "MB "; 83 | } else if (size / 1024 >= 1) { 84 | resultSize = DF.format((double) ((float) size / 1024.0F)) + "KB "; 85 | } else { 86 | resultSize = size + "B "; 87 | } 88 | 89 | return resultSize; 90 | } 91 | 92 | /** 93 | * 获取项目根路径 94 | * 95 | * @return 96 | */ 97 | public static String getResourceBasePath() { 98 | // 获取跟目录 99 | File path = null; 100 | try { 101 | path = new File(ResourceUtils.getURL("classpath:").getPath()); 102 | } catch (FileNotFoundException e) { 103 | // nothing to do 104 | } 105 | if (path == null || !path.exists()) { 106 | path = new File(""); 107 | } 108 | String pathStr = path.getAbsolutePath(); 109 | // 如果是在eclipse中运行,则和target同级目录,如果是jar部署到服务器,则默认和jar包同级 110 | pathStr = pathStr.replace("\\target\\classes", ""); 111 | return pathStr; 112 | } 113 | 114 | /** 115 | * 保证拷贝的文件的目录一定要存在 116 | * 117 | * @param filePath 118 | * 文件路径 119 | */ 120 | public static void ensureDirectory(String filePath) { 121 | if (StrUtil.isBlank(filePath)) { 122 | return; 123 | } 124 | //将符号“\\”和“\”替换成“/”,有时候便于统一的处理路径的分隔符,避免同一个路径出现两个或三种不同的分隔符 125 | filePath = filePath.replace("\\", "/").replace("\\\\", "/"); 126 | File file = new File(filePath); 127 | if (!file.exists()) { 128 | file.mkdirs(); 129 | } 130 | } 131 | 132 | /** 133 | * 上传文件保存 134 | * @param rootPath 135 | * @param bizPath 136 | * @param mf 137 | * @return 138 | * @throws IOException 139 | */ 140 | public static String fileSave(String rootPath, String bizPath, MultipartFile mf) throws IOException { 141 | log.info("--------文件正在保存---------" ); 142 | String ctxPath = rootPath; 143 | File file = new File(ctxPath + File.separator + bizPath); 144 | if (!file.exists()) { 145 | file.mkdirs();// 创建文件根目录 146 | } 147 | String orgName = mf.getOriginalFilename();// 获取文件名 148 | String filePrefixName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis(); 149 | String fileName = filePrefixName + orgName.substring(orgName.indexOf(".")); 150 | String savePath = file.getPath() + File.separator + fileName; 151 | File savefile = new File(savePath); 152 | FileCopyUtils.copy(mf.getBytes(), savefile); 153 | String dbpath = bizPath + File.separator + fileName; 154 | if (dbpath.contains("\\")) { 155 | dbpath = dbpath.replace("\\", "/"); 156 | } 157 | log.info("--------文件成功保存至" + dbpath); 158 | return dbpath; 159 | } 160 | 161 | /** 162 | * 删除指定的文件 163 | * 164 | * @param strFileName 指定绝对路径的文件名 165 | * @return 如果删除成功true否则false 166 | */ 167 | public static boolean delete(String strFileName) { 168 | File fileDelete = new File(strFileName); 169 | if (!fileDelete.exists() || !fileDelete.isFile()) { 170 | log.info("错误: " + strFileName + "不存在!"); 171 | return false; 172 | } 173 | log.info("--------成功删除文件---------" + strFileName); 174 | return fileDelete.delete(); 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /springboot-file/src/main/resources/application.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ronwxy/springboot-demos/c79579d3b46f07af477e6c56e2d566a434d05ccf/springboot-file/src/main/resources/application.yaml -------------------------------------------------------------------------------- /springboot-firstapp/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-firstapp 13 | 1.0.0-SNAPSHOT 14 | springboot-firstapp 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /springboot-firstapp/src/main/java/cn/jboost/springboot/firstapp/HelloController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.firstapp; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RequestParam; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController("/hello") 8 | public class HelloController { 9 | 10 | @GetMapping 11 | public String hello(@RequestParam(name = "name")String name){ 12 | return "您好," + name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /springboot-firstapp/src/main/java/cn/jboost/springboot/firstapp/SpringbootFirstappApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.firstapp; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootFirstappApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootFirstappApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-firstapp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /springboot-firstapp/src/test/java/cn/jboost/springboot/firstapp/SpringbootFirstappApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.firstapp; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootFirstappApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-java 13 | 1.0.0-SNAPSHOT 14 | springboot-java 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | org.junit.vintage 34 | junit-vintage-engine 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /springboot-java/src/main/java/cn/jboost/springboot/java/DateTimeBean.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.java; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import org.springframework.format.annotation.DateTimeFormat; 5 | 6 | import java.io.Serializable; 7 | import java.time.LocalDate; 8 | import java.time.LocalDateTime; 9 | import java.time.LocalTime; 10 | 11 | /*** 12 | * 13 | * @Author ronwxy 14 | * @Date 2019/11/1 16:59 15 | */ 16 | 17 | public class DateTimeBean implements Serializable { 18 | 19 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS") 20 | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS") 21 | private LocalDateTime dateTime; 22 | // @JsonFormat(pattern = "yyyy-MM-dd") 23 | private LocalDate date; 24 | private LocalTime time; 25 | 26 | public LocalDateTime getDateTime() { 27 | return dateTime; 28 | } 29 | 30 | public void setDateTime(LocalDateTime dateTime) { 31 | this.dateTime = dateTime; 32 | } 33 | 34 | public LocalDate getDate() { 35 | return date; 36 | } 37 | 38 | public void setDate(LocalDate date) { 39 | this.date = date; 40 | } 41 | 42 | public LocalTime getTime() { 43 | return time; 44 | } 45 | 46 | public void setTime(LocalTime time) { 47 | this.time = time; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /springboot-java/src/main/java/cn/jboost/springboot/java/LocalDateTimeController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.java; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.*; 6 | 7 | import java.time.LocalDate; 8 | import java.time.LocalDateTime; 9 | import java.time.LocalTime; 10 | 11 | /*** 12 | * 13 | * @Author ronwxy 14 | * @Date 2019/11/1 17:08 15 | */ 16 | @RestController 17 | @RequestMapping("local-date-time") 18 | public class LocalDateTimeController { 19 | 20 | 21 | @PostMapping 22 | public ResponseEntity setDateTime(@RequestBody DateTimeBean dateTimeBean){ 23 | return new ResponseEntity(dateTimeBean, HttpStatus.OK); 24 | } 25 | 26 | @GetMapping 27 | public ResponseEntity getDateTime(){ 28 | DateTimeBean dateTimeBean = new DateTimeBean(); 29 | dateTimeBean.setDateTime(LocalDateTime.now()); 30 | dateTimeBean.setDate(LocalDate.now()); 31 | dateTimeBean.setTime(LocalTime.now()); 32 | return new ResponseEntity(dateTimeBean, HttpStatus.OK); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /springboot-java/src/main/java/cn/jboost/springboot/java/LocalDateTimeFormatConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.java; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.Primary; 14 | 15 | import java.time.LocalDate; 16 | import java.time.LocalDateTime; 17 | import java.time.LocalTime; 18 | import java.time.format.DateTimeFormatter; 19 | 20 | /*** 21 | * 22 | * @Author ronwxy 23 | * @Date 2019/11/1 16:58 24 | */ 25 | @Configuration 26 | public class LocalDateTimeFormatConfig { 27 | private static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; 28 | private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd"; 29 | private static final String DEFAULT_TIME_PATTERN = "HH:mm:ss"; 30 | 31 | @Bean 32 | @Primary 33 | public ObjectMapper objectMapper(){ 34 | ObjectMapper objectMapper = new ObjectMapper(); 35 | JavaTimeModule javaTimeModule = new JavaTimeModule(); 36 | javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN))); 37 | javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN))); 38 | javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN))); 39 | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN))); 40 | javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN))); 41 | javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN))); 42 | objectMapper.registerModule(javaTimeModule); 43 | return objectMapper; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /springboot-java/src/main/java/cn/jboost/springboot/java/SpringbootJavaApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.java; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootJavaApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootJavaApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-java/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /springboot-java/src/test/java/cn/jboost/springboot/java/SpringbootJavaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.java; 2 | 3 | 4 | import org.junit.Test; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | 7 | @SpringBootTest 8 | class SpringbootJavaApplicationTests { 9 | 10 | @Test 11 | void contextLoads() { 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /springboot-limiter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.0.RELEASE 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-limiter 14 | 15 | 16 | 17 | cn.jboost.springboot 18 | limiter-spring-boot-starter 19 | 1.3-SNAPSHOT 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-data-redis 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /springboot-limiter/src/main/java/cn/jboost/springboot/limiter/LimiterApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.limiter; 2 | 3 | 4 | import cn.jboost.springboot.autoconfig.web.Swagger2AutoConfiguration; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | 8 | @SpringBootApplication(exclude = {Swagger2AutoConfiguration.class}) 9 | public class LimiterApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(LimiterApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /springboot-limiter/src/main/java/cn/jboost/springboot/limiter/LimiterController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.limiter; 2 | 3 | import cn.jboost.springboot.autoconfig.limiter.*; 4 | import cn.jboost.springboot.common.exception.ExceptionUtil; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.time.LocalDateTime; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * @Author ronwxy 16 | * @Date 2020/7/15 17:22 17 | * @Version 1.0 18 | */ 19 | @RestController 20 | @RequestMapping("limiter") 21 | public class LimiterController { 22 | 23 | @Autowired 24 | private RedisRateLimiterFactory redisRateLimiterFactory; 25 | 26 | /** 27 | * 注解形式 28 | * @param key 29 | * @return 30 | */ 31 | @GetMapping("/count") 32 | @CountLimit(key = "#{key}", limit = 2, period = 10, limitType = LimitType.CUSTOM) 33 | public String testCountLimit(@RequestParam("key") String key){ 34 | return "test count limiter..."; 35 | } 36 | 37 | /** 38 | * 注解形式 39 | * @param key 40 | * @return 41 | */ 42 | @GetMapping("/rate") 43 | @RateLimit(rate = 1.0/5, burst = 5.0, expire = 120, timeout = 1) 44 | public String testRateLimit(@RequestParam("key") String key){ 45 | return "test rate limiter..."; 46 | } 47 | 48 | /** 49 | * 代码段形式 50 | * @param 51 | * @return 52 | */ 53 | @GetMapping("/rate2") 54 | public String testRateLimit(){ 55 | RedisRateLimiter limiter = redisRateLimiterFactory.build("LimiterController.testRateLimit", 1.0/30, 30, 120); 56 | if(!limiter.tryAcquire("app.limiter", 0, TimeUnit.SECONDS)) { 57 | System.out.println(LocalDateTime.now()); 58 | ExceptionUtil.rethrowClientSideException("您的访问过于频繁,请稍后重试"); 59 | } 60 | return "test rate limiter 2..."; 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /springboot-limiter/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: limiter-demo 4 | redis: 5 | #数据库索引 6 | database: 0 7 | host: 192.168.40.92 8 | port: 6379 9 | password: Passw1rd 10 | #连接超时时间 11 | timeout: 2000 -------------------------------------------------------------------------------- /springboot-mybatisplus/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cn.jboost.springboot 7 | spring-boot-parent 8 | 1.2-SNAPSHOT 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-mybatisplus 14 | 15 | 16 | 17 | cn.jboost.springboot 18 | mybatisplus-spring-boot-starter 19 | 1.2-SNAPSHOT 20 | 21 | 22 | com.h2database 23 | h2 24 | runtime 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/App.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @MapperScan("cn.jboost.springboot.mybatisplus.mapper") 9 | public class App { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(App.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/LocalDateTimeFormatConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Primary; 13 | 14 | import java.time.LocalDate; 15 | import java.time.LocalDateTime; 16 | import java.time.LocalTime; 17 | import java.time.format.DateTimeFormatter; 18 | 19 | /*** 20 | * 21 | * @Author ronwxy 22 | * @Date 2019/11/1 16:58 23 | */ 24 | //@Configuration 25 | public class LocalDateTimeFormatConfig { 26 | private static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; 27 | private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd"; 28 | private static final String DEFAULT_TIME_PATTERN = "HH:mm:ss"; 29 | 30 | @Bean 31 | @Primary 32 | public ObjectMapper objectMapper(){ 33 | ObjectMapper objectMapper = new ObjectMapper(); 34 | JavaTimeModule javaTimeModule = new JavaTimeModule(); 35 | javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN))); 36 | javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN))); 37 | javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN))); 38 | javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN))); 39 | javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN))); 40 | javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN))); 41 | objectMapper.registerModule(javaTimeModule); 42 | return objectMapper; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus.controller; 2 | 3 | import cn.jboost.springboot.mybatisplus.controller.criteria.UserQueryCriteria; 4 | import cn.jboost.springboot.mybatisplus.entity.User; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | @RequestMapping("/user") 10 | public class UserController extends BaseController { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/controller/criteria/UserQueryCriteria.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus.controller.criteria; 2 | 3 | import cn.jboost.springboot.common.annotation.Query; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | @Data 9 | public class UserQueryCriteria { 10 | 11 | @Query(type = Query.Type.BETWEEN, propName = "age") 12 | private Integer[] ageRange; 13 | 14 | @Query(type = Query.Type.LIKE) 15 | private String name; 16 | 17 | @Query(type = Query.Type.IN, propName = "id") 18 | private List ids; 19 | } 20 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/entity/User.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | @Data 8 | public class User { 9 | private Long id; 10 | private String name; 11 | private Integer age; 12 | private String email; 13 | // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 14 | private LocalDateTime createTime; 15 | private LocalDateTime updateTime; 16 | } 17 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus.mapper; 2 | 3 | import cn.jboost.springboot.mybatisplus.entity.User; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface UserMapper extends BaseMapper { 9 | } 10 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/java/cn/jboost/springboot/mybatisplus/service/UserService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.mybatisplus.service; 2 | 3 | import cn.jboost.springboot.autoconfig.mybatisplus.service.BaseService; 4 | import cn.jboost.springboot.mybatisplus.entity.User; 5 | import org.springframework.stereotype.Service; 6 | 7 | @Service 8 | public class UserService extends BaseService { 9 | } 10 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # DataSource Config 2 | spring: 3 | datasource: 4 | driver-class-name: org.h2.Driver 5 | schema: classpath:db/schema-h2.sql 6 | data: classpath:db/data-h2.sql 7 | url: jdbc:h2:mem:test 8 | username: root 9 | password: test 10 | 11 | # Logger Config 12 | logging: 13 | level: 14 | com.baomidou.mybatisplus.samples.wrapper: debug 15 | 16 | #logging: 17 | # level: 18 | # root: debug -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/resources/db/data-h2.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM user; 2 | 3 | INSERT INTO user (id, name, age, email) 4 | VALUES (1, '张三', 18, 'mail1@jboost.cn'), 5 | (2, '张三丰', 20, 'mail1@jboost.cn'), 6 | (3, '李四', 28, 'mail1@jboost.cn'), 7 | (4, '李四姨', 21, 'mail1@jboost.cn'), 8 | (5, '隔壁王五', 24, 'mail1@jboost.cn'); 9 | 10 | -------------------------------------------------------------------------------- /springboot-mybatisplus/src/main/resources/db/schema-h2.sql: -------------------------------------------------------------------------------- 1 | -- noinspection SqlNoDataSourceInspectionForFile 2 | 3 | DROP TABLE IF EXISTS user; 4 | 5 | CREATE TABLE user 6 | ( 7 | id BIGINT (20) NOT NULL COMMENT '主键ID', 8 | name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', 9 | age INT (11) NULL DEFAULT NULL COMMENT '年龄', 10 | email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', 11 | create_time datetime NULL DEFAULT NULL COMMENT '创建时间', 12 | update_time datetime NULL DEFAULT NULL COMMENT '更新时间', 13 | PRIMARY KEY (id) 14 | ); -------------------------------------------------------------------------------- /springboot-properties/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-properties 13 | 1.0.0-SNAPSHOT 14 | springboot-properties 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-actuator 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /springboot-properties/src/main/java/cn/jboost/springboot/properties/MyConfigProperties.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | /*** 7 | * @Desc 8 | * @Author ronwxy 9 | * @Date 2019/6/10 17:53 10 | */ 11 | @Component 12 | @ConfigurationProperties(prefix = "my") 13 | public class MyConfigProperties { 14 | private String name; 15 | private String website; 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public String getWebsite() { 26 | return website; 27 | } 28 | 29 | public void setWebsite(String website) { 30 | this.website = website; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /springboot-properties/src/main/java/cn/jboost/springboot/properties/MyPropertiesUtil.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.properties; 2 | 3 | import java.util.Properties; 4 | 5 | /*** 6 | * @Desc 传统自定义属性读取工具类 7 | * @Author ronwxy 8 | * @Date 2019/6/10 17:37 9 | */ 10 | public class MyPropertiesUtil { 11 | 12 | private static Properties properties; 13 | 14 | public static void init(Properties props) { 15 | properties = props; 16 | } 17 | 18 | public static String getValue(String key) { 19 | return properties.getProperty(key); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /springboot-properties/src/main/java/cn/jboost/springboot/properties/SpringbootPropertiesApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.properties; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ImportResource; 6 | 7 | @SpringBootApplication 8 | @ImportResource("classpath:applicationContext.xml") 9 | public class SpringbootPropertiesApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringbootPropertiesApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /springboot-properties/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | my.name=jboost@properties.dev 2 | my.website=blog.jboost.cn@properties.dev 3 | -------------------------------------------------------------------------------- /springboot-properties/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | my: 2 | name: jboost@yml.dev 3 | website: blog.jboost.cn@yml.dev -------------------------------------------------------------------------------- /springboot-properties/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | my.name=jboost@properties 2 | my.website=blog.jboost.cn@properties 3 | 4 | 5 | management.endpoints.web.exposure.include= * 6 | management.endpoints.web.exposure.exclude=beans,trace 7 | management.endpoint.health.show-details=ALWAYS -------------------------------------------------------------------------------- /springboot-properties/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | my: 2 | name: jboost@yml 3 | website: blog.jboost.cn@yml 4 | 5 | spring: 6 | profiles: 7 | active: dev -------------------------------------------------------------------------------- /springboot-properties/src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /springboot-properties/src/main/resources/my.properties: -------------------------------------------------------------------------------- 1 | my.name=jboost 2 | my.website=blog.jboost.cn -------------------------------------------------------------------------------- /springboot-properties/src/test/java/cn/jboost/springboot/properties/SpringbootPropertiesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.properties; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootPropertiesApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-properties/src/test/java/cn/jboost/springboot/properties/SpringbootPropertiesHandleTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.properties; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.core.env.Environment; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | /*** 12 | * @Desc Springboot 访问自定义属性 13 | * @Author ronwxy 14 | * @Date 2019/6/10 17:53 15 | */ 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | public class SpringbootPropertiesHandleTest { 19 | 20 | @Autowired 21 | private MyConfigProperties myConfigProperties; 22 | 23 | @Test 24 | public void testConfigurationProperties(){ 25 | System.out.println("test @ConfigurationProperties =========="); 26 | System.out.println(myConfigProperties.getName()); 27 | System.out.println(myConfigProperties.getWebsite()); 28 | } 29 | 30 | @Value("${my.name}") 31 | private String name; 32 | @Value("${my.website}") 33 | private String website; 34 | 35 | @Test 36 | public void testValue(){ 37 | System.out.println("test @Value =========="); 38 | System.out.println(name); 39 | System.out.println(website); 40 | } 41 | 42 | @Autowired 43 | private Environment env; 44 | 45 | @Test 46 | public void testEnvironment(){ 47 | System.out.println("test Environment =========="); 48 | System.out.println(env.getProperty("my.name")); 49 | System.out.println(env.getProperty("my.website", "default value")); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /springboot-properties/src/test/java/cn/jboost/springboot/properties/TraditionalPropertiesHandleTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.properties; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | /*** 9 | * @Desc 传统自定义属性获取测试 10 | * @Author ronwxy 11 | * @Date 2019/6/10 17:42 12 | */ 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class TraditionalPropertiesHandleTest { 16 | 17 | @Test 18 | public void test(){ 19 | System.out.println(MyPropertiesUtil.getValue("my.name")); 20 | System.out.println(MyPropertiesUtil.getValue("my.website")); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /springboot-redis-cluster/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-redis-cluster 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter-test 19 | test 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-data-redis 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | 1.18.8 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/java/cn/jboost/springboot/redis/cluster/RedisClusterApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class RedisClusterApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(RedisClusterApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/java/cn/jboost/springboot/redis/cluster/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.data.redis.connection.RedisConnectionFactory; 10 | import org.springframework.data.redis.core.RedisTemplate; 11 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 12 | import org.springframework.data.redis.serializer.StringRedisSerializer; 13 | 14 | @Configuration 15 | @EnableCaching 16 | public class RedisConfig { 17 | 18 | @Bean 19 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 20 | RedisTemplate template = new RedisTemplate<>(); 21 | template.setConnectionFactory(factory); 22 | 23 | // 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化 24 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 25 | ObjectMapper om = new ObjectMapper(); 26 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 27 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 28 | jackson2JsonRedisSerializer.setObjectMapper(om); 29 | 30 | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 31 | 32 | // key采用String的序列化方式 33 | template.setKeySerializer(stringRedisSerializer); 34 | // hash的key也采用String的序列化方式 35 | template.setHashKeySerializer(stringRedisSerializer); 36 | // value序列化方式采用jackson 37 | template.setValueSerializer(jackson2JsonRedisSerializer); 38 | // hash的value序列化方式采用jackson 39 | template.setHashValueSerializer(jackson2JsonRedisSerializer); 40 | template.afterPropertiesSet(); 41 | return template; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/java/cn/jboost/springboot/redis/cluster/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster.controller; 2 | 3 | 4 | import cn.jboost.springboot.redis.cluster.entity.User; 5 | import cn.jboost.springboot.redis.cluster.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | @RestController 10 | @RequestMapping("user") 11 | public class UserController { 12 | 13 | @Autowired 14 | private UserService userService; 15 | 16 | @PostMapping 17 | public User addUser(@RequestBody User user){ 18 | return userService.addUser(user); 19 | } 20 | 21 | @PostMapping("/2") 22 | public User addUser2(@RequestBody User user){ 23 | return userService.addUser2(user); 24 | } 25 | 26 | @GetMapping 27 | public User queryByUsername(@RequestParam("username") String username) { 28 | return userService.queryByUsername(username); 29 | } 30 | 31 | @DeleteMapping("/{username}") 32 | public void deleteByUsername(@PathVariable("username") String username){ 33 | userService.deleteByUsername(username); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/java/cn/jboost/springboot/redis/cluster/entity/User.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | @Data 8 | public class User implements Serializable { 9 | private String uid; 10 | private String username; 11 | private String name; 12 | private Integer age; 13 | } 14 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/java/cn/jboost/springboot/redis/cluster/service/RedisService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.data.redis.core.RedisTemplate; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.util.CollectionUtils; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Set; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | @Component 14 | public class RedisService { 15 | 16 | @Autowired 17 | private RedisTemplate redisTemplate; 18 | 19 | /** 20 | * 指定缓存失效时间 21 | * 22 | * @param key 键 23 | * @param time 时间(秒) 24 | * @return 25 | */ 26 | public boolean expire(String key, long time) { 27 | try { 28 | if (time > 0) { 29 | redisTemplate.expire(key, time, TimeUnit.SECONDS); 30 | } 31 | return true; 32 | } catch (Exception e) { 33 | return false; 34 | } 35 | } 36 | 37 | /** 38 | * 根据key获取过期时间 39 | * 40 | * @param key 键 不能为null 41 | * @return 时间(秒) 返回0代表为永久有效 42 | */ 43 | public long getExpire(String key) { 44 | return redisTemplate.getExpire(key, TimeUnit.SECONDS); 45 | } 46 | 47 | /** 48 | * 判断key是否存在 49 | * 50 | * @param key 键 51 | * @return true 存在 false不存在 52 | */ 53 | public boolean hasKey(String key) { 54 | try { 55 | return redisTemplate.hasKey(key); 56 | } catch (Exception e) { 57 | return false; 58 | } 59 | } 60 | 61 | /** 62 | * 删除缓存 63 | * 64 | * @param key 可以传一个值 或多个 65 | */ 66 | @SuppressWarnings("unchecked") 67 | public void del(String... key) { 68 | if (key != null && key.length > 0) { 69 | if (key.length == 1) { 70 | redisTemplate.delete(key[0]); 71 | } else { 72 | redisTemplate.delete(CollectionUtils.arrayToList(key)); 73 | } 74 | } 75 | } 76 | 77 | /** 78 | * 普通缓存获取 79 | * 80 | * @param key 键 81 | * @return 值 82 | */ 83 | public Object get(String key) { 84 | return key == null ? null : redisTemplate.opsForValue().get(key); 85 | } 86 | 87 | /** 88 | * 普通缓存放入 89 | * 90 | * @param key 键 91 | * @param value 值 92 | * @return true成功 false失败 93 | */ 94 | public boolean set(String key, Object value) { 95 | try { 96 | redisTemplate.opsForValue().set(key, value); 97 | return true; 98 | } catch (Exception e) { 99 | return false; 100 | } 101 | 102 | } 103 | 104 | /** 105 | * 普通缓存放入并设置时间 106 | * 107 | * @param key 键 108 | * @param value 值 109 | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 110 | * @return true成功 false 失败 111 | */ 112 | public boolean set(String key, Object value, long time) { 113 | try { 114 | if (time > 0) { 115 | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); 116 | } else { 117 | set(key, value); 118 | } 119 | return true; 120 | } catch (Exception e) { 121 | return false; 122 | } 123 | } 124 | 125 | /** 126 | * 递增 127 | * 128 | * @param key 键 129 | * @param delta 要增加几(大于0) 130 | * @return 131 | */ 132 | public long incr(String key, long delta) { 133 | if (delta <= 0) { 134 | throw new RuntimeException("递增因子必须大于0"); 135 | } 136 | return redisTemplate.opsForValue().increment(key, delta); 137 | } 138 | 139 | /** 140 | * 递减 141 | * 142 | * @param key 键 143 | * @param delta 要减少几(小于0) 144 | * @return 145 | */ 146 | public long decr(String key, long delta) { 147 | if (delta <= 0) { 148 | throw new RuntimeException("递减因子必须大于0"); 149 | } 150 | return redisTemplate.opsForValue().increment(key, -delta); 151 | } 152 | 153 | /** 154 | * HashGet 155 | * 156 | * @param key 键 不能为null 157 | * @param item 项 不能为null 158 | * @return 值 159 | */ 160 | public Object hget(String key, String item) { 161 | return redisTemplate.opsForHash().get(key, item); 162 | } 163 | 164 | /** 165 | * 获取hashKey对应的所有键值 166 | * 167 | * @param key 键 168 | * @return 对应的多个键值 169 | */ 170 | public Map hmget(String key) { 171 | return redisTemplate.opsForHash().entries(key); 172 | } 173 | 174 | /** 175 | * HashSet 176 | * 177 | * @param key 键 178 | * @param map 对应多个键值 179 | * @return true 成功 false 失败 180 | */ 181 | public boolean hmset(String key, Map map) { 182 | try { 183 | redisTemplate.opsForHash().putAll(key, map); 184 | return true; 185 | } catch (Exception e) { 186 | return false; 187 | } 188 | } 189 | 190 | /** 191 | * HashSet 并设置时间 192 | * 193 | * @param key 键 194 | * @param map 对应多个键值 195 | * @param time 时间(秒) 196 | * @return true成功 false失败 197 | */ 198 | public boolean hmset(String key, Map map, long time) { 199 | try { 200 | redisTemplate.opsForHash().putAll(key, map); 201 | if (time > 0) { 202 | expire(key, time); 203 | } 204 | return true; 205 | } catch (Exception e) { 206 | return false; 207 | } 208 | } 209 | 210 | /** 211 | * 向一张hash表中放入数据,如果不存在将创建 212 | * 213 | * @param key 键 214 | * @param item 项 215 | * @param value 值 216 | * @return true 成功 false失败 217 | */ 218 | public boolean hset(String key, String item, Object value) { 219 | try { 220 | redisTemplate.opsForHash().put(key, item, value); 221 | return true; 222 | } catch (Exception e) { 223 | return false; 224 | } 225 | } 226 | 227 | /** 228 | * 向一张hash表中放入数据,如果不存在将创建 229 | * 230 | * @param key 键 231 | * @param item 项 232 | * @param value 值 233 | * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 234 | * @return true 成功 false失败 235 | */ 236 | public boolean hset(String key, String item, Object value, long time) { 237 | try { 238 | redisTemplate.opsForHash().put(key, item, value); 239 | if (time > 0) { 240 | expire(key, time); 241 | } 242 | return true; 243 | } catch (Exception e) { 244 | return false; 245 | } 246 | } 247 | 248 | /** 249 | * 删除hash表中的值 250 | * 251 | * @param key 键 不能为null 252 | * @param item 项 可以使多个 不能为null 253 | */ 254 | public void hdel(String key, Object... item) { 255 | redisTemplate.opsForHash().delete(key, item); 256 | } 257 | 258 | /** 259 | * 判断hash表中是否有该项的值 260 | * 261 | * @param key 键 不能为null 262 | * @param item 项 不能为null 263 | * @return true 存在 false不存在 264 | */ 265 | public boolean hHasKey(String key, String item) { 266 | return redisTemplate.opsForHash().hasKey(key, item); 267 | } 268 | 269 | /** 270 | * hash递增 如果不存在,就会创建一个 并把新增后的值返回 271 | * 272 | * @param key 键 273 | * @param item 项 274 | * @param by 要增加几(大于0) 275 | * @return 276 | */ 277 | public double hincr(String key, String item, double by) { 278 | return redisTemplate.opsForHash().increment(key, item, by); 279 | } 280 | 281 | /** 282 | * hash递减 283 | * 284 | * @param key 键 285 | * @param item 项 286 | * @param by 要减少记(小于0) 287 | * @return 288 | */ 289 | public double hdecr(String key, String item, double by) { 290 | return redisTemplate.opsForHash().increment(key, item, -by); 291 | } 292 | 293 | /** 294 | * 根据key获取Set中的所有值 295 | * 296 | * @param key 键 297 | * @return 298 | */ 299 | public Set sGet(String key) { 300 | try { 301 | return redisTemplate.opsForSet().members(key); 302 | } catch (Exception e) { 303 | return null; 304 | } 305 | } 306 | 307 | /** 308 | * 根据value从一个set中查询,是否存在 309 | * 310 | * @param key 键 311 | * @param value 值 312 | * @return true 存在 false不存在 313 | */ 314 | public boolean sHasKey(String key, Object value) { 315 | try { 316 | return redisTemplate.opsForSet().isMember(key, value); 317 | } catch (Exception e) { 318 | return false; 319 | } 320 | } 321 | 322 | /** 323 | * 将数据放入set缓存 324 | * 325 | * @param key 键 326 | * @param values 值 可以是多个 327 | * @return 成功个数 328 | */ 329 | public long sSet(String key, Object... values) { 330 | try { 331 | return redisTemplate.opsForSet().add(key, values); 332 | } catch (Exception e) { 333 | return 0; 334 | } 335 | } 336 | 337 | /** 338 | * 将set数据放入缓存 339 | * 340 | * @param key 键 341 | * @param time 时间(秒) 342 | * @param values 值 可以是多个 343 | * @return 成功个数 344 | */ 345 | public long sSetAndTime(String key, long time, Object... values) { 346 | try { 347 | Long count = redisTemplate.opsForSet().add(key, values); 348 | if (time > 0) 349 | expire(key, time); 350 | return count; 351 | } catch (Exception e) { 352 | return 0; 353 | } 354 | } 355 | 356 | /** 357 | * 获取set缓存的长度 358 | * 359 | * @param key 键 360 | * @return 361 | */ 362 | public long sGetSetSize(String key) { 363 | try { 364 | return redisTemplate.opsForSet().size(key); 365 | } catch (Exception e) { 366 | return 0; 367 | } 368 | } 369 | 370 | /** 371 | * 移除值为value的 372 | * 373 | * @param key 键 374 | * @param values 值 可以是多个 375 | * @return 移除的个数 376 | */ 377 | public long setRemove(String key, Object... values) { 378 | try { 379 | Long count = redisTemplate.opsForSet().remove(key, values); 380 | return count; 381 | } catch (Exception e) { 382 | return 0; 383 | } 384 | } 385 | 386 | /** 387 | * 获取list缓存的内容 388 | * 389 | * @param key 键 390 | * @param start 开始 391 | * @param end 结束 0 到 -1代表所有值 392 | * @return 393 | */ 394 | public List lGet(String key, long start, long end) { 395 | try { 396 | return redisTemplate.opsForList().range(key, start, end); 397 | } catch (Exception e) { 398 | return null; 399 | } 400 | } 401 | 402 | /** 403 | * 获取list缓存的长度 404 | * 405 | * @param key 键 406 | * @return 407 | */ 408 | public long lGetListSize(String key) { 409 | try { 410 | return redisTemplate.opsForList().size(key); 411 | } catch (Exception e) { 412 | return 0; 413 | } 414 | } 415 | 416 | /** 417 | * 通过索引 获取list中的值 418 | * 419 | * @param key 键 420 | * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 421 | * @return 422 | */ 423 | public Object lGetIndex(String key, long index) { 424 | try { 425 | return redisTemplate.opsForList().index(key, index); 426 | } catch (Exception e) { 427 | return null; 428 | } 429 | } 430 | 431 | /** 432 | * 将list放入缓存 433 | * 434 | * @param key 键 435 | * @param value 值 436 | * @return 437 | */ 438 | public boolean lSet(String key, Object value) { 439 | try { 440 | redisTemplate.opsForList().rightPush(key, value); 441 | return true; 442 | } catch (Exception e) { 443 | return false; 444 | } 445 | } 446 | 447 | /** 448 | * 将list放入缓存 449 | * 450 | * @param key 键 451 | * @param value 值 452 | * @param time 时间(秒) 453 | * @return 454 | */ 455 | public boolean lSet(String key, Object value, long time) { 456 | try { 457 | redisTemplate.opsForList().rightPush(key, value); 458 | if (time > 0) 459 | expire(key, time); 460 | return true; 461 | } catch (Exception e) { 462 | return false; 463 | } 464 | } 465 | 466 | /** 467 | * 将list放入缓存 468 | * 469 | * @param key 键 470 | * @param value 值 471 | * @return 472 | */ 473 | public boolean lSet(String key, List value) { 474 | try { 475 | redisTemplate.opsForList().rightPushAll(key, value); 476 | return true; 477 | } catch (Exception e) { 478 | return false; 479 | } 480 | } 481 | 482 | /** 483 | * 将list放入缓存 484 | * 485 | * @param key 键 486 | * @param value 值 487 | * @param time 时间(秒) 488 | * @return 489 | */ 490 | public boolean lSet(String key, List value, long time) { 491 | try { 492 | redisTemplate.opsForList().rightPushAll(key, value); 493 | if (time > 0) 494 | expire(key, time); 495 | return true; 496 | } catch (Exception e) { 497 | return false; 498 | } 499 | } 500 | 501 | /** 502 | * 根据索引修改list中的某条数据 503 | * 504 | * @param key 键 505 | * @param index 索引 506 | * @param value 值 507 | * @return 508 | */ 509 | public boolean lUpdateIndex(String key, long index, Object value) { 510 | try { 511 | redisTemplate.opsForList().set(key, index, value); 512 | return true; 513 | } catch (Exception e) { 514 | e.printStackTrace(); 515 | return false; 516 | } 517 | } 518 | 519 | /** 520 | * 移除N个值为value 521 | * 522 | * @param key 键 523 | * @param count 移除多少个 524 | * @param value 值 525 | * @return 移除的个数 526 | */ 527 | public long lRemove(String key, long count, Object value) { 528 | try { 529 | Long remove = redisTemplate.opsForList().remove(key, count, value); 530 | return remove; 531 | } catch (Exception e) { 532 | return 0; 533 | } 534 | } 535 | 536 | } 537 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/java/cn/jboost/springboot/redis/cluster/service/UserService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster.service; 2 | 3 | import cn.jboost.springboot.redis.cluster.entity.User; 4 | import org.springframework.cache.annotation.*; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.UUID; 10 | 11 | @Service 12 | @CacheConfig(cacheNames = "users") 13 | public class UserService { 14 | 15 | private static Map userMap = new HashMap<>(); 16 | 17 | @CachePut(key = "#user.username") 18 | public User addUser(User user){ 19 | user.setUid(UUID.randomUUID().toString()); 20 | System.out.println("add user: " + user); 21 | userMap.put(user.getUsername(), user); 22 | return user; 23 | } 24 | 25 | @Caching(put = { 26 | @CachePut( key = "#user.username"), 27 | @CachePut( key = "#user.uid") 28 | }) 29 | public User addUser2(User user) { 30 | user.setUid(UUID.randomUUID().toString()); 31 | System.out.println("add user2: " + user); 32 | userMap.put(user.getUsername(), user); 33 | return user; 34 | } 35 | 36 | @Cacheable( key = "#p0", condition = "#p0 != null") 37 | public User queryByUsername(String username) { 38 | System.out.println("query from map..."); 39 | return userMap.get(username); 40 | } 41 | 42 | @CacheEvict(key = "#username", condition = "#username != null") 43 | public void deleteByUsername(String username) { 44 | userMap.remove(username); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: redis-cluster-demo 4 | 5 | redis: 6 | password: passw0rd 7 | timeout: 5000 8 | database: 0 9 | cluster: 10 | nodes: 192.168.40.201:7100,192.168.40.201:7200,192.168.40.201:7300,192.168.40.201:7400,192.168.40.201:7500,192.168.40.201:7600 11 | max-redirects: 3 12 | jedis: 13 | pool: 14 | max-active: 8 15 | max-wait: -1 16 | max-idle: 8 17 | min-idle: 0 18 | 19 | server: 20 | port: 8080 21 | -------------------------------------------------------------------------------- /springboot-redis-cluster/src/test/java/cn/jboost/springboot/redis/cluster/test/RedisTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.cluster.test; 2 | 3 | import cn.jboost.springboot.redis.cluster.service.RedisService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | @RunWith(SpringRunner.class) 11 | @SpringBootTest 12 | public class RedisTest { 13 | 14 | @Autowired 15 | private RedisService redisService; 16 | 17 | @Test 18 | public void testCache() { 19 | redisService.set("site", "blog.jboost.cn.3"); 20 | System.out.println(redisService.get("site")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-redis-sentinel 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter-test 19 | test 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-data-redis 29 | 30 | 31 | io.lettuce 32 | lettuce-core 33 | 34 | 35 | 36 | 37 | redis.clients 38 | jedis 39 | 2.9.0 40 | 41 | 42 | org.projectlombok 43 | lombok 44 | 1.18.8 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/java/cn/jboost/springboot/redis/sentinel/RedisSentinelApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class RedisSentinelApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(RedisSentinelApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/java/cn/jboost/springboot/redis/sentinel/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.data.redis.connection.RedisConnectionFactory; 10 | import org.springframework.data.redis.core.RedisTemplate; 11 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 12 | import org.springframework.data.redis.serializer.StringRedisSerializer; 13 | 14 | @Configuration 15 | @EnableCaching 16 | public class RedisConfig { 17 | 18 | @Bean 19 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 20 | RedisTemplate template = new RedisTemplate<>(); 21 | template.setConnectionFactory(factory); 22 | 23 | // 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化 24 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 25 | ObjectMapper om = new ObjectMapper(); 26 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 27 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 28 | jackson2JsonRedisSerializer.setObjectMapper(om); 29 | 30 | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 31 | 32 | // key采用String的序列化方式 33 | template.setKeySerializer(stringRedisSerializer); 34 | // hash的key也采用String的序列化方式 35 | template.setHashKeySerializer(stringRedisSerializer); 36 | // value序列化方式采用jackson 37 | template.setValueSerializer(jackson2JsonRedisSerializer); 38 | // hash的value序列化方式采用jackson 39 | template.setHashValueSerializer(jackson2JsonRedisSerializer); 40 | template.afterPropertiesSet(); 41 | return template; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/java/cn/jboost/springboot/redis/sentinel/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel.controller; 2 | 3 | import cn.jboost.springboot.redis.sentinel.entity.User; 4 | import cn.jboost.springboot.redis.sentinel.service.UserService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | @RestController 9 | @RequestMapping("user") 10 | public class UserController { 11 | 12 | @Autowired 13 | private UserService userService; 14 | 15 | @PostMapping 16 | public User addUser(@RequestBody User user){ 17 | return userService.addUser(user); 18 | } 19 | 20 | @PostMapping("/2") 21 | public User addUser2(@RequestBody User user){ 22 | return userService.addUser2(user); 23 | } 24 | 25 | @GetMapping 26 | public User queryByUsername(@RequestParam("username") String username) { 27 | return userService.queryByUsername(username); 28 | } 29 | 30 | @DeleteMapping("/{username}") 31 | public void deleteByUsername(@PathVariable("username") String username){ 32 | userService.deleteByUsername(username); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/java/cn/jboost/springboot/redis/sentinel/entity/User.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | @Data 8 | public class User implements Serializable { 9 | private String uid; 10 | private String username; 11 | private String name; 12 | private Integer age; 13 | } 14 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/java/cn/jboost/springboot/redis/sentinel/service/RedisService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.data.redis.core.RedisTemplate; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.util.CollectionUtils; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Set; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | @Component 15 | @Slf4j 16 | public class RedisService { 17 | 18 | @Autowired 19 | private RedisTemplate redisTemplate; 20 | 21 | /** 22 | * 指定缓存失效时间 23 | * 24 | * @param key 键 25 | * @param time 时间(秒) 26 | * @return 27 | */ 28 | public boolean expire(String key, long time) { 29 | try { 30 | if (time > 0) { 31 | redisTemplate.expire(key, time, TimeUnit.SECONDS); 32 | } 33 | return true; 34 | } catch (Exception e) { 35 | log.error("exception when expire key {}. ", key, e); 36 | return false; 37 | } 38 | } 39 | 40 | /** 41 | * 根据key获取过期时间 42 | * 43 | * @param key 键 不能为null 44 | * @return 时间(秒) 返回0代表为永久有效 45 | */ 46 | public long getExpire(String key) { 47 | return redisTemplate.getExpire(key, TimeUnit.SECONDS); 48 | } 49 | 50 | /** 51 | * 判断key是否存在 52 | * 53 | * @param key 键 54 | * @return true 存在 false不存在 55 | */ 56 | public boolean hasKey(String key) { 57 | try { 58 | return redisTemplate.hasKey(key); 59 | } catch (Exception e) { 60 | log.error("exception when check key {}. ", key, e); 61 | return false; 62 | } 63 | } 64 | 65 | /** 66 | * 删除缓存 67 | * 68 | * @param key 可以传一个值 或多个 69 | */ 70 | @SuppressWarnings("unchecked") 71 | public void del(String... key) { 72 | if (key != null && key.length > 0) { 73 | if (key.length == 1) { 74 | redisTemplate.delete(key[0]); 75 | } else { 76 | redisTemplate.delete(CollectionUtils.arrayToList(key)); 77 | } 78 | } 79 | } 80 | 81 | /** 82 | * 普通缓存获取 83 | * 84 | * @param key 键 85 | * @return 值 86 | */ 87 | public Object get(String key) { 88 | return key == null ? null : redisTemplate.opsForValue().get(key); 89 | } 90 | 91 | /** 92 | * 普通缓存放入 93 | * 94 | * @param key 键 95 | * @param value 值 96 | * @return true成功 false失败 97 | */ 98 | public boolean set(String key, Object value) { 99 | try { 100 | redisTemplate.opsForValue().set(key, value); 101 | return true; 102 | } catch (Exception e) { 103 | log.error("exception when set key {}. ", key, e); 104 | return false; 105 | } 106 | 107 | } 108 | 109 | /** 110 | * 普通缓存放入并设置时间 111 | * 112 | * @param key 键 113 | * @param value 值 114 | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 115 | * @return true成功 false 失败 116 | */ 117 | public boolean set(String key, Object value, long time) { 118 | try { 119 | if (time > 0) { 120 | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); 121 | } else { 122 | set(key, value); 123 | } 124 | return true; 125 | } catch (Exception e) { 126 | log.error("exception when set key {}. ", key, e); 127 | return false; 128 | } 129 | } 130 | 131 | /** 132 | * 递增 133 | * 134 | * @param key 键 135 | * @param delta 要增加几(大于0) 136 | * @return 137 | */ 138 | public long incr(String key, long delta) { 139 | if (delta <= 0) { 140 | throw new RuntimeException("递增因子必须大于0"); 141 | } 142 | return redisTemplate.opsForValue().increment(key, delta); 143 | } 144 | 145 | /** 146 | * 递减 147 | * 148 | * @param key 键 149 | * @param delta 要减少几(小于0) 150 | * @return 151 | */ 152 | public long decr(String key, long delta) { 153 | if (delta <= 0) { 154 | throw new RuntimeException("递减因子必须大于0"); 155 | } 156 | return redisTemplate.opsForValue().increment(key, -delta); 157 | } 158 | 159 | /** 160 | * HashGet 161 | * 162 | * @param key 键 不能为null 163 | * @param item 项 不能为null 164 | * @return 值 165 | */ 166 | public Object hget(String key, String item) { 167 | return redisTemplate.opsForHash().get(key, item); 168 | } 169 | 170 | /** 171 | * 获取hashKey对应的所有键值 172 | * 173 | * @param key 键 174 | * @return 对应的多个键值 175 | */ 176 | public Map hmget(String key) { 177 | return redisTemplate.opsForHash().entries(key); 178 | } 179 | 180 | /** 181 | * HashSet 182 | * 183 | * @param key 键 184 | * @param map 对应多个键值 185 | * @return true 成功 false 失败 186 | */ 187 | public boolean hmset(String key, Map map) { 188 | try { 189 | redisTemplate.opsForHash().putAll(key, map); 190 | return true; 191 | } catch (Exception e) { 192 | log.error("exception when hash set key {}. ", key, e); 193 | return false; 194 | } 195 | } 196 | 197 | /** 198 | * HashSet 并设置时间 199 | * 200 | * @param key 键 201 | * @param map 对应多个键值 202 | * @param time 时间(秒) 203 | * @return true成功 false失败 204 | */ 205 | public boolean hmset(String key, Map map, long time) { 206 | try { 207 | redisTemplate.opsForHash().putAll(key, map); 208 | if (time > 0) { 209 | expire(key, time); 210 | } 211 | return true; 212 | } catch (Exception e) { 213 | log.error("exception when hash set key {}. ", key, e); 214 | return false; 215 | } 216 | } 217 | 218 | /** 219 | * 向一张hash表中放入数据,如果不存在将创建 220 | * 221 | * @param key 键 222 | * @param item 项 223 | * @param value 值 224 | * @return true 成功 false失败 225 | */ 226 | public boolean hset(String key, String item, Object value) { 227 | try { 228 | redisTemplate.opsForHash().put(key, item, value); 229 | return true; 230 | } catch (Exception e) { 231 | log.error("exception when hash set key {}, item {} ", key, item, e); 232 | return false; 233 | } 234 | } 235 | 236 | /** 237 | * 向一张hash表中放入数据,如果不存在将创建 238 | * 239 | * @param key 键 240 | * @param item 项 241 | * @param value 值 242 | * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 243 | * @return true 成功 false失败 244 | */ 245 | public boolean hset(String key, String item, Object value, long time) { 246 | try { 247 | redisTemplate.opsForHash().put(key, item, value); 248 | if (time > 0) { 249 | expire(key, time); 250 | } 251 | return true; 252 | } catch (Exception e) { 253 | log.error("exception when hash set key {}, item {} ", key, item, e); 254 | return false; 255 | } 256 | } 257 | 258 | /** 259 | * 删除hash表中的值 260 | * 261 | * @param key 键 不能为null 262 | * @param item 项 可以使多个 不能为null 263 | */ 264 | public void hdel(String key, Object... item) { 265 | redisTemplate.opsForHash().delete(key, item); 266 | } 267 | 268 | /** 269 | * 判断hash表中是否有该项的值 270 | * 271 | * @param key 键 不能为null 272 | * @param item 项 不能为null 273 | * @return true 存在 false不存在 274 | */ 275 | public boolean hHasKey(String key, String item) { 276 | return redisTemplate.opsForHash().hasKey(key, item); 277 | } 278 | 279 | /** 280 | * hash递增 如果不存在,就会创建一个 并把新增后的值返回 281 | * 282 | * @param key 键 283 | * @param item 项 284 | * @param by 要增加几(大于0) 285 | * @return 286 | */ 287 | public double hincr(String key, String item, double by) { 288 | return redisTemplate.opsForHash().increment(key, item, by); 289 | } 290 | 291 | /** 292 | * hash递减 293 | * 294 | * @param key 键 295 | * @param item 项 296 | * @param by 要减少记(小于0) 297 | * @return 298 | */ 299 | public double hdecr(String key, String item, double by) { 300 | return redisTemplate.opsForHash().increment(key, item, -by); 301 | } 302 | 303 | /** 304 | * 根据key获取Set中的所有值 305 | * 306 | * @param key 键 307 | * @return 308 | */ 309 | public Set sGet(String key) { 310 | try { 311 | return redisTemplate.opsForSet().members(key); 312 | } catch (Exception e) { 313 | return null; 314 | } 315 | } 316 | 317 | /** 318 | * 根据value从一个set中查询,是否存在 319 | * 320 | * @param key 键 321 | * @param value 值 322 | * @return true 存在 false不存在 323 | */ 324 | public boolean sHasKey(String key, Object value) { 325 | try { 326 | return redisTemplate.opsForSet().isMember(key, value); 327 | } catch (Exception e) { 328 | return false; 329 | } 330 | } 331 | 332 | /** 333 | * 将数据放入set缓存 334 | * 335 | * @param key 键 336 | * @param values 值 可以是多个 337 | * @return 成功个数 338 | */ 339 | public long sSet(String key, Object... values) { 340 | try { 341 | return redisTemplate.opsForSet().add(key, values); 342 | } catch (Exception e) { 343 | return 0; 344 | } 345 | } 346 | 347 | /** 348 | * 将set数据放入缓存 349 | * 350 | * @param key 键 351 | * @param time 时间(秒) 352 | * @param values 值 可以是多个 353 | * @return 成功个数 354 | */ 355 | public long sSetAndTime(String key, long time, Object... values) { 356 | try { 357 | Long count = redisTemplate.opsForSet().add(key, values); 358 | if (time > 0) 359 | expire(key, time); 360 | return count; 361 | } catch (Exception e) { 362 | return 0; 363 | } 364 | } 365 | 366 | /** 367 | * 获取set缓存的长度 368 | * 369 | * @param key 键 370 | * @return 371 | */ 372 | public long sGetSetSize(String key) { 373 | try { 374 | return redisTemplate.opsForSet().size(key); 375 | } catch (Exception e) { 376 | return 0; 377 | } 378 | } 379 | 380 | /** 381 | * 移除值为value的 382 | * 383 | * @param key 键 384 | * @param values 值 可以是多个 385 | * @return 移除的个数 386 | */ 387 | public long setRemove(String key, Object... values) { 388 | try { 389 | Long count = redisTemplate.opsForSet().remove(key, values); 390 | return count; 391 | } catch (Exception e) { 392 | return 0; 393 | } 394 | } 395 | 396 | /** 397 | * 获取list缓存的内容 398 | * 399 | * @param key 键 400 | * @param start 开始 401 | * @param end 结束 0 到 -1代表所有值 402 | * @return 403 | */ 404 | public List lGet(String key, long start, long end) { 405 | try { 406 | return redisTemplate.opsForList().range(key, start, end); 407 | } catch (Exception e) { 408 | return null; 409 | } 410 | } 411 | 412 | /** 413 | * 获取list缓存的长度 414 | * 415 | * @param key 键 416 | * @return 417 | */ 418 | public long lGetListSize(String key) { 419 | try { 420 | return redisTemplate.opsForList().size(key); 421 | } catch (Exception e) { 422 | return 0; 423 | } 424 | } 425 | 426 | /** 427 | * 通过索引 获取list中的值 428 | * 429 | * @param key 键 430 | * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 431 | * @return 432 | */ 433 | public Object lGetIndex(String key, long index) { 434 | try { 435 | return redisTemplate.opsForList().index(key, index); 436 | } catch (Exception e) { 437 | return null; 438 | } 439 | } 440 | 441 | /** 442 | * 将list放入缓存 443 | * 444 | * @param key 键 445 | * @param value 值 446 | * @return 447 | */ 448 | public boolean lSet(String key, Object value) { 449 | try { 450 | redisTemplate.opsForList().rightPush(key, value); 451 | return true; 452 | } catch (Exception e) { 453 | return false; 454 | } 455 | } 456 | 457 | /** 458 | * 将list放入缓存 459 | * 460 | * @param key 键 461 | * @param value 值 462 | * @param time 时间(秒) 463 | * @return 464 | */ 465 | public boolean lSet(String key, Object value, long time) { 466 | try { 467 | redisTemplate.opsForList().rightPush(key, value); 468 | if (time > 0) 469 | expire(key, time); 470 | return true; 471 | } catch (Exception e) { 472 | return false; 473 | } 474 | } 475 | 476 | /** 477 | * 将list放入缓存 478 | * 479 | * @param key 键 480 | * @param value 值 481 | * @return 482 | */ 483 | public boolean lSet(String key, List value) { 484 | try { 485 | redisTemplate.opsForList().rightPushAll(key, value); 486 | return true; 487 | } catch (Exception e) { 488 | return false; 489 | } 490 | } 491 | 492 | /** 493 | * 将list放入缓存 494 | * 495 | * @param key 键 496 | * @param value 值 497 | * @param time 时间(秒) 498 | * @return 499 | */ 500 | public boolean lSet(String key, List value, long time) { 501 | try { 502 | redisTemplate.opsForList().rightPushAll(key, value); 503 | if (time > 0) 504 | expire(key, time); 505 | return true; 506 | } catch (Exception e) { 507 | return false; 508 | } 509 | } 510 | 511 | /** 512 | * 根据索引修改list中的某条数据 513 | * 514 | * @param key 键 515 | * @param index 索引 516 | * @param value 值 517 | * @return 518 | */ 519 | public boolean lUpdateIndex(String key, long index, Object value) { 520 | try { 521 | redisTemplate.opsForList().set(key, index, value); 522 | return true; 523 | } catch (Exception e) { 524 | e.printStackTrace(); 525 | return false; 526 | } 527 | } 528 | 529 | /** 530 | * 移除N个值为value 531 | * 532 | * @param key 键 533 | * @param count 移除多少个 534 | * @param value 值 535 | * @return 移除的个数 536 | */ 537 | public long lRemove(String key, long count, Object value) { 538 | try { 539 | Long remove = redisTemplate.opsForList().remove(key, count, value); 540 | return remove; 541 | } catch (Exception e) { 542 | return 0; 543 | } 544 | } 545 | 546 | } 547 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/java/cn/jboost/springboot/redis/sentinel/service/UserService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel.service; 2 | 3 | import cn.jboost.springboot.redis.sentinel.entity.User; 4 | import org.springframework.cache.annotation.*; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.UUID; 10 | 11 | @Service 12 | @CacheConfig(cacheNames = "users") 13 | public class UserService { 14 | 15 | private static Map userMap = new HashMap<>(); 16 | 17 | @CachePut(key = "#user.username") 18 | public User addUser(User user){ 19 | user.setUid(UUID.randomUUID().toString()); 20 | System.out.println("add user: " + user); 21 | userMap.put(user.getUsername(), user); 22 | return user; 23 | } 24 | 25 | @Caching(put = { 26 | @CachePut( key = "#user.username"), 27 | @CachePut( key = "#user.uid") 28 | }) 29 | public User addUser2(User user) { 30 | user.setUid(UUID.randomUUID().toString()); 31 | System.out.println("add user2: " + user); 32 | userMap.put(user.getUsername(), user); 33 | return user; 34 | } 35 | 36 | @Cacheable( key = "#p0", condition = "#p0 != null") 37 | public User queryByUsername(String username) { 38 | System.out.println("query from map..."); 39 | return userMap.get(username); 40 | } 41 | 42 | @CacheEvict(key = "#username", condition = "#username != null") 43 | public void deleteByUsername(String username) { 44 | userMap.remove(username); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: redis-sentinel-demo 4 | 5 | redis: 6 | password: passw0rd 7 | timeout: 5000 8 | sentinel: 9 | master: mymaster 10 | nodes: 192.168.40.201:26379,192.168.40.201:36379,192.168.40.201:46379 11 | jedis: 12 | pool: 13 | max-active: 8 14 | max-wait: -1s 15 | max-idle: 8 16 | min-idle: 0 17 | server: 18 | port: 8080 19 | -------------------------------------------------------------------------------- /springboot-redis-sentinel/src/test/java/cn/jboost/springboot/redis/sentinel/test/RedisTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.sentinel.test; 2 | 3 | import cn.jboost.springboot.redis.sentinel.service.RedisService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | @RunWith(SpringRunner.class) 11 | @SpringBootTest 12 | public class RedisTest { 13 | 14 | @Autowired 15 | private RedisService redisService; 16 | 17 | @Test 18 | public void testCache() { 19 | redisService.set("site", "blog.jboost.cn"); 20 | System.out.println(redisService.get("site")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /springboot-redis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springboot-demos 7 | com.jboost.springboot 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | springboot-redis 14 | 15 | 16 | 8 17 | 8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-test 24 | test 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-data-redis 29 | 30 | 31 | redis.clients 32 | jedis 33 | 2.9.0 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /springboot-redis/src/main/java/cn/jboost/springboot/redis/Application.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @Author ronwxy 8 | * @Date 2021/1/28 11:32 9 | * @Version 1.0 10 | */ 11 | @SpringBootApplication 12 | public class Application { 13 | public static void main(String[] args) { 14 | SpringApplication.run(Application.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /springboot-redis/src/main/java/cn/jboost/springboot/redis/RedisKeyExpirationListener.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis; 2 | 3 | import org.springframework.data.redis.connection.Message; 4 | import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; 5 | import org.springframework.data.redis.listener.RedisMessageListenerContainer; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | * @Author ronwxy 11 | * @Date 2021/1/28 9:58 12 | * @Version 1.0 13 | */ 14 | public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { 15 | 16 | public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { 17 | super(listenerContainer); 18 | } 19 | 20 | /** 21 | * 针对redis数据失效事件,进行数据处理 22 | * 23 | * @param message 24 | * @param pattern 25 | */ 26 | @Override 27 | public void onMessage(Message message, byte[] pattern) { 28 | String expiredKey = message.toString(); 29 | System.out.printf(LocalDateTime.now().toString()); 30 | System.out.println("expire key:" + expiredKey); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /springboot-redis/src/main/java/cn/jboost/springboot/redis/RedisListenerConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.data.redis.connection.RedisConnectionFactory; 6 | import org.springframework.data.redis.listener.RedisMessageListenerContainer; 7 | 8 | /** 9 | * @Author ronwxy 10 | * @Date 2021/1/28 9:14 11 | * @Version 1.0 12 | */ 13 | @Configuration 14 | public class RedisListenerConfig { 15 | 16 | @Bean 17 | public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { 18 | RedisMessageListenerContainer container = new RedisMessageListenerContainer(); 19 | container.setConnectionFactory(connectionFactory); 20 | return container; 21 | } 22 | 23 | @Bean 24 | public RedisKeyExpirationListener keyExpirationListener(RedisMessageListenerContainer listenerContainer) { 25 | return new RedisKeyExpirationListener(listenerContainer); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot-redis/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | redis: 3 | #数据库索引 4 | database: 8 5 | host: 192.168.40.92 6 | port: 6379 7 | password: Passw1rd 8 | #连接超时时间 9 | timeout: 2000 -------------------------------------------------------------------------------- /springboot-redis/src/test/java/cn/jboost/springboot/redis/test/RedisTest.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.redis.test; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.data.redis.core.RedisTemplate; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | import java.time.LocalDateTime; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * @Author ronwxy 15 | * @Date 2021/1/28 9:12 16 | * @Version 1.0 17 | */ 18 | @RunWith(SpringRunner.class) 19 | @SpringBootTest 20 | public class RedisTest { 21 | 22 | @Autowired 23 | private RedisTemplate redisTemplate; 24 | 25 | @Test 26 | public void testExpire() throws InterruptedException { 27 | System.out.printf(LocalDateTime.now().toString()); 28 | redisTemplate.boundValueOps("test.key").set("test-expire"); 29 | redisTemplate.boundValueOps("test.key").expire(5, TimeUnit.SECONDS); 30 | Thread.sleep(10000); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /springboot-security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springboot-demos 7 | com.jboost.springboot 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springboot-security 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-security 18 | 2.3.0.RELEASE 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 2.3.0.RELEASE 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/Application.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security; 2 | 3 | 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.security.core.userdetails.User; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @Author ronwxy 14 | * @Date 2020/8/10 14:17 15 | * @Version 1.0 16 | */ 17 | @SpringBootApplication 18 | public class Application { 19 | 20 | public static final Map usernameMap = new HashMap<>(); 21 | public static final Map phoneMap = new HashMap<>(); 22 | 23 | public static void main(String[] args) { 24 | usernameMap.put("test", new User("test","$2a$10$e5TdbQpb9X6i8VySWpH02.5bARx4At5APp5.XlPOyYY1daFQ2i3kK", new ArrayList<>(0))); 25 | usernameMap.put("jboost", new User("jboost","$2a$10$e5TdbQpb9X6i8VySWpH02.5bARx4At5APp5.XlPOyYY1daFQ2i3kK", new ArrayList<>(0))); 26 | SpringApplication.run(Application.class, args); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/HelloController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security; 2 | 3 | import org.springframework.security.core.userdetails.User; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @Author ronwxy 12 | * @Date 2020/8/10 15:01 13 | * @Version 1.0 14 | */ 15 | @RestController 16 | public class HelloController { 17 | 18 | @GetMapping("/users") 19 | public List hello() { 20 | List users = new ArrayList<>(); 21 | users.addAll(Application.usernameMap.values()); 22 | users.addAll(Application.phoneMap.values()); 23 | return users; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/JboostAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security; 2 | 3 | import cn.jboost.springboot.security.phone.PhoneAuthenticationToken; 4 | import cn.jboost.springboot.security.username.UsernameAuthenticationToken; 5 | import cn.jboost.springboot.security.util.LoginParam; 6 | import cn.jboost.springboot.security.util.LoginType; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.security.authentication.AuthenticationServiceException; 10 | import org.springframework.security.authentication.BadCredentialsException; 11 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 12 | import org.springframework.security.core.Authentication; 13 | import org.springframework.security.core.AuthenticationException; 14 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 15 | 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.io.IOException; 19 | 20 | /** 21 | * @Author ronwxy 22 | * @Date 2020/8/10 14:44 23 | * @Version 1.0 24 | */ 25 | public class JboostAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 26 | 27 | private static final ObjectMapper objectMapper = new ObjectMapper(); 28 | 29 | @Override 30 | public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 31 | if (!request.getMethod().equals("POST") || !request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) { 32 | throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 33 | } else { 34 | UsernamePasswordAuthenticationToken authentication = null; 35 | try { 36 | LoginParam loginParam = objectMapper.readValue(request.getInputStream(), LoginParam.class); 37 | if(LoginType.USER.equals(loginParam.getLoginType())){ 38 | authentication = new UsernameAuthenticationToken(loginParam.getUsername() == null ? "": loginParam.getUsername().trim(), 39 | loginParam.getPassword() == null ? "":loginParam.getPassword(), 40 | loginParam.getUserType(), loginParam.getUuid(), loginParam.getCode()); 41 | 42 | } else if(LoginType.PHONE.equals(loginParam.getLoginType())) { 43 | authentication = new PhoneAuthenticationToken(loginParam.getPhone() == null ? "":loginParam.getPhone().trim(), 44 | loginParam.getCode(), loginParam.getUserType()); 45 | } else { 46 | throw new BadCredentialsException("不支持的登录类型"); 47 | } 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | 52 | this.setDetails(request, authentication); 53 | return this.getAuthenticationManager().authenticate(authentication); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security; 2 | 3 | import cn.jboost.springboot.security.phone.PhoneAuthenticationProvider; 4 | import cn.jboost.springboot.security.phone.PhoneUserDetailsService; 5 | import cn.jboost.springboot.security.username.CompositeUserDetailsChecker; 6 | import cn.jboost.springboot.security.username.RetryLimitAfterPasswordFailedChecker; 7 | import cn.jboost.springboot.security.username.UsernameAuthenticationProvider; 8 | import cn.jboost.springboot.security.username.UsernameUserDetailsService; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.http.HttpStatus; 13 | import org.springframework.http.ResponseEntity; 14 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 15 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 16 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 17 | import org.springframework.security.core.Authentication; 18 | import org.springframework.security.core.AuthenticationException; 19 | import org.springframework.security.core.userdetails.UserDetailsChecker; 20 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 21 | import org.springframework.security.crypto.password.PasswordEncoder; 22 | import org.springframework.security.web.authentication.AuthenticationFailureHandler; 23 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 24 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 25 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 26 | 27 | import javax.servlet.ServletException; 28 | import javax.servlet.http.HttpServletRequest; 29 | import javax.servlet.http.HttpServletResponse; 30 | import java.io.IOException; 31 | import java.io.PrintWriter; 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | /** 36 | * @Author ronwxy 37 | * @Date 2020/8/10 14:32 38 | * @Version 1.0 39 | */ 40 | @Configuration 41 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 42 | 43 | @Override 44 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 45 | UsernameAuthenticationProvider usernameAuthenticationProvider = new UsernameAuthenticationProvider(); 46 | usernameAuthenticationProvider.setUserDetailsService(new UsernameUserDetailsService()); 47 | usernameAuthenticationProvider.setPasswordEncoder(passwordEncoder()); 48 | List checkers = new ArrayList<>(1); 49 | checkers.add(new RetryLimitAfterPasswordFailedChecker()); 50 | usernameAuthenticationProvider.setAfterPasswordInvalidChecker(new CompositeUserDetailsChecker(checkers)); 51 | auth.authenticationProvider(usernameAuthenticationProvider); 52 | 53 | PhoneAuthenticationProvider phoneAuthenticationProvider = new PhoneAuthenticationProvider(); 54 | phoneAuthenticationProvider.setUserDetailsService(new PhoneUserDetailsService()); 55 | auth.authenticationProvider(phoneAuthenticationProvider); 56 | } 57 | 58 | @Override 59 | protected void configure(HttpSecurity http) throws Exception { 60 | http.authorizeRequests() 61 | .anyRequest().authenticated() 62 | .and() 63 | // .formLogin() 64 | //// .loginPage("/login") 65 | //// .loginProcessingUrl("doLogin") 66 | // .and() 67 | .csrf() 68 | .disable(); 69 | http.addFilterAt(jboostAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); 70 | } 71 | 72 | @Bean 73 | public JboostAuthenticationFilter jboostAuthenticationFilter() throws Exception { 74 | JboostAuthenticationFilter authenticationFilter = new JboostAuthenticationFilter(); 75 | authenticationFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() { 76 | @Override 77 | public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException { 78 | resp.setContentType("application/json;charset=utf-8"); 79 | PrintWriter out = resp.getWriter(); 80 | ResponseEntity respBean = ResponseEntity.ok("登录成功!"); 81 | out.write(new ObjectMapper().writeValueAsString(respBean)); 82 | out.flush(); 83 | out.close(); 84 | } 85 | }); 86 | authenticationFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() { 87 | @Override 88 | public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException { 89 | resp.setContentType("application/json;charset=utf-8"); 90 | PrintWriter out = resp.getWriter(); 91 | ResponseEntity respBean = new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST); 92 | out.write(new ObjectMapper().writeValueAsString(respBean)); 93 | out.flush(); 94 | out.close(); 95 | } 96 | }); 97 | authenticationFilter.setAuthenticationManager(super.authenticationManagerBean()); 98 | authenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST")); 99 | return authenticationFilter; 100 | } 101 | 102 | @Bean 103 | PasswordEncoder passwordEncoder() { 104 | return new BCryptPasswordEncoder(); 105 | } 106 | 107 | public static void main(String[] args) { 108 | System.out.println(new BCryptPasswordEncoder().encode("jboost123")); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/phone/PhoneAuthenticationProvider.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.phone; 2 | 3 | import cn.jboost.springboot.security.Application; 4 | import org.springframework.security.authentication.BadCredentialsException; 5 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 6 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 7 | import org.springframework.security.core.AuthenticationException; 8 | import org.springframework.security.core.userdetails.User; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | 11 | /** 12 | * @Author ronwxy 13 | * @Date 2020/8/10 16:04 14 | * @Version 1.0 15 | */ 16 | public class PhoneAuthenticationProvider extends DaoAuthenticationProvider { 17 | 18 | 19 | @Override 20 | protected void additionalAuthenticationChecks(UserDetails userDetails, 21 | UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 22 | 23 | if(!"123456".equals(authentication.getCredentials().toString())) { 24 | throw new BadCredentialsException("验证码错误"); 25 | } 26 | if(! Application.phoneMap.containsKey(userDetails.getUsername())) { 27 | Application.phoneMap.put(userDetails.getUsername(), (User) userDetails); 28 | } 29 | } 30 | 31 | @Override 32 | public boolean supports(Class authentication) { 33 | return PhoneAuthenticationToken.class.isAssignableFrom(authentication); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/phone/PhoneAuthenticationToken.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.phone; 2 | 3 | import cn.jboost.springboot.security.util.UserType; 4 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 5 | 6 | /** 7 | * @Author ronwxy 8 | * @Date 2020/8/10 18:12 9 | * @Version 1.0 10 | */ 11 | public class PhoneAuthenticationToken extends UsernamePasswordAuthenticationToken { 12 | 13 | private UserType userType; 14 | 15 | public PhoneAuthenticationToken(Object principal, Object credentials, UserType userType) { 16 | super(principal, credentials); 17 | this.userType = userType; 18 | } 19 | 20 | public UserType getUserType() { 21 | return userType; 22 | } 23 | 24 | public void setUserType(UserType userType) { 25 | this.userType = userType; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/phone/PhoneUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.phone; 2 | 3 | import cn.jboost.springboot.security.Application; 4 | import org.springframework.security.core.userdetails.User; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * @Author ronwxy 13 | * @Date 2020/8/11 8:10 14 | * @Version 1.0 15 | */ 16 | public class PhoneUserDetailsService implements UserDetailsService { 17 | 18 | @Override 19 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 20 | for(String phone : Application.phoneMap.keySet()) { 21 | if(phone.equals(username)) { 22 | return Application.phoneMap.get(phone); 23 | } 24 | } 25 | return new User(username, "123321", new ArrayList<>(0)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/username/CompositeUserDetailsChecker.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.username; 2 | 3 | import org.springframework.security.core.userdetails.UserDetails; 4 | import org.springframework.security.core.userdetails.UserDetailsChecker; 5 | import org.springframework.util.CollectionUtils; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | /** 12 | * UserDetails 校验器组合 13 | * @Author ronwxy 14 | * @Date 2020/8/8 10:23 15 | * @Version 1.0 16 | */ 17 | public class CompositeUserDetailsChecker implements UserDetailsChecker { 18 | private List checkers; 19 | 20 | public CompositeUserDetailsChecker(List checkers) { 21 | this.checkers = checkers; 22 | } 23 | 24 | public List getCheckers() { 25 | return Optional.ofNullable(checkers).orElse(new ArrayList<>()); 26 | } 27 | 28 | @Override 29 | public void check(UserDetails toCheck) { 30 | if (CollectionUtils.isEmpty(checkers)) { 31 | return; 32 | } 33 | checkers.stream().forEach(c -> c.check(toCheck)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/username/RetryLimitAfterPasswordFailedChecker.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.username; 2 | 3 | import org.springframework.security.authentication.BadCredentialsException; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | import org.springframework.security.core.userdetails.UserDetailsChecker; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * @Author ronwxy 12 | * @Date 2020/8/11 10:24 13 | * @Version 1.0 14 | */ 15 | public class RetryLimitAfterPasswordFailedChecker implements UserDetailsChecker { 16 | 17 | private static final Map limitMap = new HashMap<>(); 18 | private static final int LIMIT = 3; 19 | 20 | @Override 21 | public void check(UserDetails toCheck) { 22 | if(limitMap.containsKey(toCheck.getUsername())) { 23 | if(limitMap.get(toCheck.getUsername()) == LIMIT) { 24 | throw new BadCredentialsException("密码重试超过最大次数,请半小时后再试或联系管理员"); 25 | } else { 26 | limitMap.put(toCheck.getUsername(), limitMap.get(toCheck.getUsername()) + 1); 27 | } 28 | } else { 29 | limitMap.put(toCheck.getUsername(), 1); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/username/UsernameAuthenticationProvider.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.username; 2 | 3 | import org.springframework.security.authentication.BadCredentialsException; 4 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 5 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 6 | import org.springframework.security.core.AuthenticationException; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | 9 | /** 10 | * @Author ronwxy 11 | * @Date 2020/8/10 16:04 12 | * @Version 1.0 13 | */ 14 | public class UsernameAuthenticationProvider extends DaoAuthenticationProvider { 15 | 16 | private CompositeUserDetailsChecker preChecker; 17 | private CompositeUserDetailsChecker afterPasswordInvalidChecker; 18 | 19 | public void setPreChecker(CompositeUserDetailsChecker preChecker) { 20 | this.preChecker = preChecker; 21 | } 22 | 23 | public void setAfterPasswordInvalidChecker(CompositeUserDetailsChecker afterPasswordInvalidChecker) { 24 | this.afterPasswordInvalidChecker = afterPasswordInvalidChecker; 25 | } 26 | 27 | @Override 28 | protected void additionalAuthenticationChecks(UserDetails userDetails, 29 | UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 30 | 31 | if (authentication.getCredentials() == null) { 32 | logger.debug("Authentication failed: no credentials provided"); 33 | throw new BadCredentialsException("用户名或密码错误"); 34 | } 35 | String rawPassword = authentication.getCredentials().toString(); 36 | 37 | if (!getPasswordEncoder().matches(rawPassword, userDetails.getPassword())) { 38 | logger.debug("Authentication failed: password does not match stored value"); 39 | if(afterPasswordInvalidChecker != null) { 40 | afterPasswordInvalidChecker.check(userDetails); 41 | } 42 | throw new BadCredentialsException("用户名或密码错误"); 43 | } 44 | } 45 | 46 | @Override 47 | public boolean supports(Class authentication) { 48 | return UsernameAuthenticationToken.class.isAssignableFrom(authentication); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/username/UsernameAuthenticationToken.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.username; 2 | 3 | import cn.jboost.springboot.security.util.UserType; 4 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 5 | 6 | /** 7 | * @Author ronwxy 8 | * @Date 2020/8/10 18:13 9 | * @Version 1.0 10 | */ 11 | public class UsernameAuthenticationToken extends UsernamePasswordAuthenticationToken { 12 | 13 | private UserType userType; 14 | private String uuid; //图形验证码uuid 15 | private String code; //验证码(图形/短信) 16 | 17 | public UsernameAuthenticationToken(Object principal, Object credentials, UserType userType, String uuid, String code) { 18 | super(principal, credentials); 19 | this.userType = userType; 20 | this.uuid = uuid; 21 | this.code = code; 22 | } 23 | 24 | public UserType getUserType() { 25 | return userType; 26 | } 27 | 28 | public void setUserType(UserType userType) { 29 | this.userType = userType; 30 | } 31 | 32 | public String getUuid() { 33 | return uuid; 34 | } 35 | 36 | public void setUuid(String uuid) { 37 | this.uuid = uuid; 38 | } 39 | 40 | public String getCode() { 41 | return code; 42 | } 43 | 44 | public void setCode(String code) { 45 | this.code = code; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/username/UsernameUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.username; 2 | 3 | import cn.jboost.springboot.security.Application; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | import org.springframework.security.core.userdetails.UserDetailsService; 6 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 7 | 8 | /** 9 | * @Author ronwxy 10 | * @Date 2020/5/20 11:41 11 | * @Version 1.0 12 | */ 13 | public class UsernameUserDetailsService implements UserDetailsService { 14 | 15 | 16 | @Override 17 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 18 | for(String uname: Application.usernameMap.keySet()) { 19 | if(uname.equals(username)){ 20 | return Application.usernameMap.get(uname); 21 | } 22 | } 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/util/LoginParam.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.util; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @Author ronwxy 7 | * @Date 2020/8/10 17:51 8 | * @Version 1.0 9 | */ 10 | public class LoginParam implements Serializable { 11 | 12 | private LoginType loginType; 13 | private UserType userType; //用户类型 14 | private String username; //用户名 15 | private String password; //密码 16 | private String uuid; //图形验证码uuid 17 | private String code; //验证码(图形/短信) 18 | private String phone; //手机号码 19 | 20 | public LoginType getLoginType() { 21 | return loginType; 22 | } 23 | 24 | public void setLoginType(LoginType loginType) { 25 | this.loginType = loginType; 26 | } 27 | 28 | public UserType getUserType() { 29 | return userType; 30 | } 31 | 32 | public void setUserType(UserType userType) { 33 | this.userType = userType; 34 | } 35 | 36 | public String getUsername() { 37 | return username; 38 | } 39 | 40 | public void setUsername(String username) { 41 | this.username = username; 42 | } 43 | 44 | public String getPassword() { 45 | return password; 46 | } 47 | 48 | public void setPassword(String password) { 49 | this.password = password; 50 | } 51 | 52 | public String getUuid() { 53 | return uuid; 54 | } 55 | 56 | public void setUuid(String uuid) { 57 | this.uuid = uuid; 58 | } 59 | 60 | public String getCode() { 61 | return code; 62 | } 63 | 64 | public void setCode(String code) { 65 | this.code = code; 66 | } 67 | 68 | public String getPhone() { 69 | return phone; 70 | } 71 | 72 | public void setPhone(String phone) { 73 | this.phone = phone; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/util/LoginType.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.util; 2 | 3 | /** 4 | * @Author ronwxy 5 | * @Date 2020/8/10 17:56 6 | * @Version 1.0 7 | */ 8 | public enum LoginType { 9 | USER, 10 | PHONE, 11 | WECHAT 12 | } 13 | -------------------------------------------------------------------------------- /springboot-security/src/main/java/cn/jboost/springboot/security/util/UserType.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.security.util; 2 | 3 | /** 4 | * @Author ronwxy 5 | * @Date 2020/8/10 17:54 6 | * @Version 1.0 7 | */ 8 | public enum UserType { 9 | ADMIN, 10 | USER 11 | } 12 | -------------------------------------------------------------------------------- /springboot-security/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | security: 3 | user: 4 | name: jboost 5 | password: jboost123 6 | roles: admin -------------------------------------------------------------------------------- /springboot-simpleauth/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | 4.0.0 12 | 13 | springboot-simpleauth 14 | 15 | 16 | 17 | 1.8 18 | 0.9.1 19 | 1.16.18 20 | 3.7 21 | 3.2.2 22 | 2.6 23 | 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | io.jsonwebtoken 38 | jjwt 39 | ${jwt.version} 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-data-redis 44 | 45 | 46 | org.projectlombok 47 | lombok 48 | ${lombok.version} 49 | 50 | 51 | org.apache.commons 52 | commons-lang3 53 | ${apache-commons-lang3.version} 54 | 55 | 56 | commons-collections 57 | commons-collections 58 | ${commons-collections.version} 59 | 60 | 61 | commons-io 62 | commons-io 63 | ${commons-io.version} 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/SimpleAuthApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /*** 7 | * 8 | * @Author ronwxy 9 | * @Date 2019/8/1 18:52 10 | */ 11 | @SpringBootApplication 12 | public class SimpleAuthApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(SimpleAuthApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/auth/AuthInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.auth; 2 | 3 | import cn.jboost.springboot.simpleauth.util.ApiResponse; 4 | import cn.jboost.springboot.simpleauth.util.WebUtil; 5 | import io.jsonwebtoken.Claims; 6 | import io.jsonwebtoken.Jwts; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.web.method.HandlerMethod; 12 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.lang.reflect.Method; 17 | 18 | /*** 19 | * 20 | * @Author ronwxy 21 | * @Date 2019/7/31 10:14 22 | */ 23 | @Component 24 | @Slf4j 25 | public class AuthInterceptor extends HandlerInterceptorAdapter { 26 | 27 | @Autowired 28 | private RedisTokenManager tokenManager; 29 | 30 | public boolean preHandle(HttpServletRequest request, 31 | HttpServletResponse response, Object handler) throws Exception { 32 | String requestPath = request.getRequestURI().substring(request.getContextPath().length()); 33 | // 如果不是映射到方法直接通过 34 | if (!(handler instanceof HandlerMethod)) { 35 | return true; 36 | } 37 | 38 | HandlerMethod handlerMethod = (HandlerMethod) handler; 39 | Method method = handlerMethod.getMethod(); 40 | // 如果方法注明了 SkipAuth,则不需要登录token验证 41 | if (method.getAnnotation(SkipAuth.class) != null) { 42 | return true; 43 | } 44 | 45 | // 从header中得到token 46 | String authorization = request.getHeader(JwtConstant.AUTHORIZATION); 47 | // 验证token 48 | if(StringUtils.isBlank(authorization)){ 49 | WebUtil.outputJsonString(ApiResponse.failed("未提供有效Token!"), response); 50 | return false; 51 | } 52 | try { 53 | Claims claims = Jwts.parser().setSigningKey(JwtConstant.JWT_SECRET).parseClaimsJws(authorization).getBody(); 54 | String userId = claims.getId(); 55 | TokenModel model = new TokenModel(userId, authorization); 56 | if (tokenManager.checkToken(model)) { 57 | // 通过ThreadLocal设置下游需要访问的值 58 | AuthUtil.setUserId(model.getUserId()); 59 | return true; 60 | } else { 61 | log.info("连接" + requestPath + "拒绝"); 62 | WebUtil.outputJsonString(ApiResponse.failed("未提供有效Token!"), response); 63 | return false; 64 | } 65 | } catch (Exception e) { 66 | log.error("连接" + requestPath + "发生错误:", e); 67 | WebUtil.outputJsonString(ApiResponse.failed("校验Token发生异常!"), response); 68 | return false; 69 | } 70 | } 71 | 72 | 73 | @Override 74 | public void afterCompletion( 75 | HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { 76 | //结束后清除,否则由于连接池复用,导致ThreadLocal的值被其他用户获取 77 | AuthUtil.clear(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/auth/AuthUtil.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.auth; 2 | 3 | /*** 4 | * 5 | * @Author ronwxy 6 | * @Date 2019/7/31 10:21 7 | */ 8 | public class AuthUtil { 9 | 10 | private static final ThreadLocal threadLocal = new ThreadLocal<>(); 11 | 12 | public static void setUserId(String userId){ 13 | threadLocal.set(userId); 14 | } 15 | 16 | public static String getUserId(){ 17 | return threadLocal.get(); 18 | } 19 | 20 | public static void clear(){ 21 | threadLocal.remove(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/auth/JwtConstant.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.auth; 2 | 3 | public class JwtConstant { 4 | 5 | /** 6 | * 上线需要变更 7 | */ 8 | public static final String JWT_SECRET = "AbcD1FgHijk1m0M"; 9 | 10 | public static final String AUTHORIZATION = "X-AUTH-TOKEN"; 11 | public static final long TOKEN_EXPIRES_HOUR = 2; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/auth/RedisTokenManager.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.auth; 2 | 3 | import io.jsonwebtoken.Jwts; 4 | import io.jsonwebtoken.SignatureAlgorithm; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.redis.core.StringRedisTemplate; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Date; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | /*** 13 | * 14 | * @Author ronwxy 15 | * @Date 2019/7/31 14:47 16 | */ 17 | @Component 18 | public class RedisTokenManager { 19 | 20 | @Autowired 21 | private StringRedisTemplate redisTemplate; 22 | 23 | /** 24 | * 生成TOKEN 25 | */ 26 | public String createToken(String userId) { 27 | //使用uuid作为源token 28 | String token = Jwts.builder().setId(userId).setIssuedAt(new Date()).signWith(SignatureAlgorithm.HS256, JwtConstant.JWT_SECRET).compact(); 29 | //存储到redis并设置过期时间 30 | redisTemplate.boundValueOps(JwtConstant.AUTHORIZATION + ":" + userId).set(token, JwtConstant.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS); 31 | return token; 32 | } 33 | 34 | public boolean checkToken(TokenModel model) { 35 | if (model == null) { 36 | return false; 37 | } 38 | String token = redisTemplate.boundValueOps(JwtConstant.AUTHORIZATION + ":" + model.getUserId()).get(); 39 | if (token == null || !token.equals(model.getToken())) { 40 | return false; 41 | } 42 | //如果验证成功,说明此用户进行了一次有效操作,延长token的过期时间 43 | redisTemplate.boundValueOps(model.getUserId()).expire(JwtConstant.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS); 44 | return true; 45 | } 46 | 47 | public void deleteToken(String userId) { 48 | redisTemplate.delete(userId); 49 | } 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/auth/SkipAuth.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.auth; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /*** 9 | * 在Controller的方法上使用此注解,不会检查用户是否登录 10 | * 未使用此注解的,都会进行登录鉴权 11 | * @Author ronwxy 12 | * @Date 2019/7/31 10:08 13 | */ 14 | @Target(ElementType.METHOD) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface SkipAuth { 17 | } 18 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/auth/TokenModel.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.auth; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /*** 8 | * 9 | * @Author ronwxy 10 | * @Date 2019/7/31 14:53 11 | */ 12 | @Getter 13 | @Setter 14 | @ToString 15 | public class TokenModel { 16 | 17 | //用户id 18 | private String userId; 19 | //jwt token 20 | private String token; 21 | 22 | public TokenModel(String userId, String token) { 23 | this.userId = userId; 24 | this.token = token; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/config/WebConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.config; 2 | 3 | import cn.jboost.springboot.simpleauth.auth.AuthInterceptor; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /*** 10 | * 11 | * @Author ronwxy 12 | * @Date 2019/7/31 10:17 13 | */ 14 | @Configuration 15 | public class WebConfiguration implements WebMvcConfigurer { 16 | 17 | private AuthInterceptor authInterceptor; 18 | 19 | @Autowired 20 | public void setAuthInterceptor(AuthInterceptor authInterceptor){ 21 | this.authInterceptor = authInterceptor; 22 | } 23 | /** 24 | * 注册鉴权拦截器 25 | * @param 26 | * @return 27 | */ 28 | public void addInterceptors(InterceptorRegistry registry) { 29 | registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns("/error"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/controller/TestContoller.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.controller; 2 | 3 | import cn.jboost.springboot.simpleauth.auth.AuthUtil; 4 | import cn.jboost.springboot.simpleauth.auth.SkipAuth; 5 | import cn.jboost.springboot.simpleauth.util.ApiResponse; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /*** 10 | * 11 | * @Author ronwxy 12 | * @Date 2019/8/1 18:49 13 | */ 14 | 15 | @RestController 16 | @RequestMapping("/test") 17 | public class TestContoller { 18 | 19 | @SkipAuth 20 | @RequestMapping("/skip-auth") 21 | public ApiResponse skipAuth() { 22 | return ApiResponse.success("不需要认证的接口调用"); 23 | } 24 | 25 | @RequestMapping("/need-auth") 26 | public ApiResponse needAuth() { 27 | return ApiResponse.success("username: " + AuthUtil.getUserId()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.controller; 2 | 3 | import cn.jboost.springboot.simpleauth.auth.RedisTokenManager; 4 | import cn.jboost.springboot.simpleauth.auth.SkipAuth; 5 | import cn.jboost.springboot.simpleauth.util.ApiResponse; 6 | import org.apache.commons.collections.MapUtils; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.Map; 13 | 14 | /*** 15 | * 16 | * @Author ronwxy 17 | * @Date 2019/8/1 18:10 18 | */ 19 | @RestController 20 | @RequestMapping("/user") 21 | public class UserController { 22 | 23 | @Autowired 24 | private RedisTokenManager tokenManager; 25 | 26 | @SkipAuth 27 | @RequestMapping("/login") 28 | public ApiResponse login(@RequestBody Map params) { 29 | String username = MapUtils.getString(params, "username"); 30 | String password = MapUtils.getString(params, "password"); 31 | if("ksxy".equals(username) && "jboost".equals(password)){ 32 | return ApiResponse.success(tokenManager.createToken(username)); 33 | } else { 34 | return ApiResponse.failed("用户名或密码错误"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/util/ApiResponse.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.util; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | import java.io.Serializable; 9 | 10 | @Getter 11 | @Setter 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class ApiResponse implements Serializable { 15 | 16 | private static int SUCCESS_CODE = 0; 17 | private static int FAILED_CODE = 1; 18 | private static String SUCCESS_MESSAGE = "操作成功!"; 19 | 20 | private int code; 21 | private String message; 22 | private Object data; 23 | 24 | public static ApiResponse success(Object data) { 25 | return new ApiResponse(SUCCESS_CODE, SUCCESS_MESSAGE, data); 26 | } 27 | 28 | public static ApiResponse failed(String errorMessage) { 29 | return new ApiResponse(FAILED_CODE, errorMessage, null); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/java/cn/jboost/springboot/simpleauth/util/WebUtil.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.simpleauth.util; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.apache.commons.io.IOUtils; 5 | 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.OutputStream; 8 | 9 | public class WebUtil { 10 | 11 | private static ObjectMapper mapper = new ObjectMapper(); 12 | 13 | public static void outputJsonString(ApiResponse data, 14 | HttpServletResponse response) { 15 | response.setContentType("application/json"); 16 | response.setHeader("Cache-Control", "no-store, no-cache"); 17 | response.setHeader("Pragma", "no-cache"); 18 | OutputStream out; 19 | try { 20 | out = response.getOutputStream(); 21 | IOUtils.write(mapper.writeValueAsString(data), out, "UTF-8"); 22 | out.flush(); 23 | out.close(); 24 | } catch (Exception ex) { 25 | throw new RuntimeException(ex); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /springboot-simpleauth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | redis: 3 | host: localhost 4 | port: 6379 5 | database: 0 6 | password: 123654 7 | timeout: 3000 8 | jedis: 9 | pool: 10 | min-idle: 2 11 | max-idle: 8 12 | max-active: 8 13 | max-wait: 1000 14 | -------------------------------------------------------------------------------- /springboot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | cn.jboost.springboot 6 | springboot-starter 7 | 1.0.0-SNAPSHOT 8 | springboot-starter 9 | Demo project for Spring Boot Starter 10 | 11 | 12 | 1.8 13 | 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-dependencies 20 | 2.1.5.RELEASE 21 | pom 22 | import 23 | 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /springboot-starter/src/main/java/cn/jboost/springboot/starter/MyAutoConfig.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.starter; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 5 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | @EnableConfigurationProperties(MyProperties.class) 11 | public class MyAutoConfig { 12 | 13 | @Autowired 14 | private MyProperties myProperties; 15 | 16 | @Bean 17 | @ConditionalOnProperty(prefix = "my", name = "disable", havingValue = "false") 18 | public MyService myService(){ 19 | return new MyService("Hi " + myProperties.getName() + ", welcome to visit " + myProperties.getWebsite()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /springboot-starter/src/main/java/cn/jboost/springboot/starter/MyProperties.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.starter; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | @ConfigurationProperties(prefix = "my") 6 | public class MyProperties { 7 | private String name; 8 | private String website; 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getWebsite() { 19 | return website; 20 | } 21 | 22 | public void setWebsite(String website) { 23 | this.website = website; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /springboot-starter/src/main/java/cn/jboost/springboot/starter/MyService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.starter; 2 | 3 | public class MyService { 4 | private String hiStr; 5 | 6 | public MyService(String hiStr){ 7 | this.hiStr = hiStr; 8 | } 9 | 10 | public String sayHi(){ 11 | return this.hiStr; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /springboot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | cn.jboost.springboot.starter.MyAutoConfig -------------------------------------------------------------------------------- /springboot-swagger/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-swagger 13 | 0.0.1-SNAPSHOT 14 | springboot-swagger 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 1.2-SNAPSHOT 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-test 26 | test 27 | 28 | 29 | 30 | cn.jboost.springboot 31 | swagger-spring-boot-starter 32 | ${jboost-springboot.version} 33 | 34 | 35 | 36 | cn.jboost.springboot 37 | web-spring-boot-starter 38 | ${jboost-springboot.version} 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /springboot-swagger/src/main/java/cn/jboost/springboot/swagger/SpringbootSwaggerApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.swagger; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootSwaggerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootSwaggerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-swagger/src/main/java/cn/jboost/springboot/swagger/SwaggerController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.swagger; 2 | 3 | import com.google.common.collect.Maps; 4 | import io.swagger.annotations.Api; 5 | import io.swagger.annotations.ApiOperation; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.Map; 9 | 10 | /*** 11 | * 12 | * @Author ronwxy 13 | * @Date 2019/6/27 18:09 14 | */ 15 | @RestController 16 | @RequestMapping("swagger") 17 | @Api(value = "测试接口",tags = "测试tags") 18 | public class SwaggerController { 19 | 20 | @GetMapping 21 | @ApiOperation(value = "GET请求",notes = "Get请求notes") 22 | public Map get(@RequestParam String user){ 23 | Map map = Maps.newHashMap(); 24 | map.put("name", "Hi " + user); 25 | map.put("website", "blog.jboost.cn"); 26 | return map; 27 | } 28 | 29 | @PostMapping 30 | @ApiOperation(value = "POST请求",notes = "POST请求notes") 31 | public Map post(@RequestBody Map map){ 32 | return map; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /springboot-swagger/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: swagger-test 7 | 8 | profiles: 9 | active: dev 10 | 11 | swagger: 12 | api-title: Demo标题 13 | api-description: Demo描述,集中注册 14 | group-name: Demo群组 15 | apis-base-package: cn.jboost.springboot.swagger 16 | swagger-register-url: http://192.168.40.208:11090/swagger/register 17 | 18 | # 开启跨域支持 19 | cors: 20 | enable: true -------------------------------------------------------------------------------- /springboot-swagger/src/test/java/cn/jboost/springboot/swagger/SpringbootSwaggerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.swagger; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootSwaggerApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springboot-tkmapper/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | cn.jboost.springboot 7 | spring-boot-parent 8 | 1.2-SNAPSHOT 9 | 10 | 11 | springboot-tkmapper 12 | springboot-tkmapper 13 | Demo project for Spring Boot 14 | 15 | 16 | 1.8 17 | 18 | 19 | 20 | 21 | mysql 22 | mysql-connector-java 23 | runtime 24 | 25 | 26 | cn.jboost.springboot 27 | tkmapper-spring-boot-starter 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-maven-plugin 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/java/cn/jboost/springboot/tkmapper/SpringbootTkmapperApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.tkmapper; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootTkmapperApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootTkmapperApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/java/cn/jboost/springboot/tkmapper/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.tkmapper.controller; 2 | 3 | import cn.jboost.springboot.autoconfig.mybatisplus.controller.BaseController; 4 | import cn.jboost.springboot.tkmapper.domain.User; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /*** 9 | * BaseController实现了基本的单表接口 10 | * @Author ronwxy 11 | * @Date 2019/6/20 18:16 12 | */ 13 | @RestController 14 | @RequestMapping("/user") 15 | public class UserController extends BaseController { 16 | 17 | // @GetMapping("test") 18 | // public List query(@ModelAttribute User user, Page page){ 19 | // 20 | // } 21 | } 22 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/java/cn/jboost/springboot/tkmapper/domain/User.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.tkmapper.domain; 2 | 3 | import cn.jboost.springboot.autoconfig.tkmapper.domain.AutoIncrementKeyBaseDomain; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | import org.apache.ibatis.type.JdbcType; 8 | import tk.mybatis.mapper.annotation.ColumnType; 9 | 10 | import javax.persistence.Table; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /*** 15 | * @Desc 16 | * @Author ronwxy 17 | * @Date 2019/6/20 8:55 18 | */ 19 | @Table(name = "user") 20 | @Getter 21 | @Setter 22 | @ToString 23 | public class User extends AutoIncrementKeyBaseDomain { 24 | private String name; 25 | @ColumnType(jdbcType = JdbcType.CHAR) 26 | private Gender gender; 27 | private List favor; 28 | private Map address; 29 | 30 | public enum Gender{ 31 | M, 32 | F 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/java/cn/jboost/springboot/tkmapper/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.tkmapper.mapper; 2 | 3 | import cn.jboost.springboot.autoconfig.tkmapper.mapper.BaseMapper; 4 | import cn.jboost.springboot.tkmapper.domain.User; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /*** 8 | * @Desc DAO bean, 可以使用{@code org.springframework.stereotype.Repository} 或 {@code org.apache.ibatis.annotations.Mapper} 9 | * @Author ronwxy 10 | * @Date 2019/6/20 8:54 11 | */ 12 | @Repository 13 | public interface UserMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/java/cn/jboost/springboot/tkmapper/service/UserService.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.tkmapper.service; 2 | 3 | import cn.jboost.springboot.autoconfig.tkmapper.service.BaseService; 4 | import cn.jboost.springboot.tkmapper.domain.User; 5 | import org.springframework.stereotype.Service; 6 | import org.springframework.transaction.annotation.Transactional; 7 | 8 | /*** 9 | * @Desc 10 | * @Author ronwxy 11 | * @Date 2019/6/20 8:59 12 | */ 13 | @Service 14 | public class UserService extends BaseService { 15 | 16 | @Transactional 17 | public void createWithTransaction(User user){ 18 | create(user); 19 | //用于测试事务 20 | throw new RuntimeException("抛出异常,让前面的数据库操作回滚"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | cors: 5 | enable: true 6 | 7 | spring: 8 | datasource: 9 | druid: 10 | driver-class-name: com.mysql.jdbc.Driver 11 | url: jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC 12 | username: root 13 | password: 14 | # 自定义配置 15 | initialSize: 2 # 初始化大小 16 | minIdle: 1 # 最小连接 17 | maxActive: 5 # 最大连接 18 | druidServletSettings: 19 | allow: 127.0.0.1 20 | deny: 21 | loginUsername: admin 22 | loginPassword: Passw0rd 23 | resetEnable: true 24 | druidFilterSettings: 25 | exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' 26 | maxWait: 60000 # 配置获取连接等待超时的时间 27 | timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 28 | minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒 29 | validationQuery: SELECT 'x' 30 | testWhileIdle: true 31 | testOnBorrow: false 32 | testOnReturn: false 33 | poolPreparedStatements: true # 打开PSCache,并且指定每个连接上PSCache的大小 34 | maxPoolPreparedStatementPerConnectionSize: 20 35 | filters: stat #,wall(添加wall代码里不能直接拼接sql,druid有sql注入校验) # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 36 | connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 37 | useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据 38 | 39 | logging: 40 | level: 41 | root: debug 42 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | create schema if not exists test collate utf8_general_ci; 2 | 3 | create table if not exists user 4 | ( 5 | id int auto_increment 6 | primary key, 7 | name varchar(20) not null comment '姓名', 8 | gender char null comment '性别', 9 | favor json null comment '爱好', 10 | address json null comment '住址' 11 | ); 12 | 13 | -------------------------------------------------------------------------------- /springboot-tkmapper/src/test/java/cn/jboost/springboot/tkmapper/SpringbootTkmapperApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.tkmapper; 2 | 3 | import cn.jboost.springboot.tkmapper.domain.User; 4 | import cn.jboost.springboot.tkmapper.service.UserService; 5 | import com.google.common.collect.Lists; 6 | import com.google.common.collect.Maps; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.test.context.junit4.SpringRunner; 13 | 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | @RunWith(SpringRunner.class) 18 | @SpringBootTest 19 | public class SpringbootTkmapperApplicationTests { 20 | 21 | @Test 22 | public void contextLoads() { 23 | } 24 | 25 | @Autowired 26 | private UserService userService; 27 | 28 | @Test 29 | public void testTkMapper(){ 30 | User user = new User(); 31 | user.setName("jboost"); 32 | user.setGender(User.Gender.F); 33 | List favor = Lists.newArrayList(); 34 | favor.add("互联网"); 35 | favor.add("电影"); 36 | favor.add("篮球"); 37 | user.setFavor(favor); 38 | Map address = Maps.newHashMap(); 39 | address.put("province", "湖南"); 40 | address.put("city", "长沙"); 41 | user.setAddress(address); 42 | 43 | userService.create(user); 44 | 45 | Assert.assertNotNull(user.getId()); 46 | } 47 | 48 | @Test 49 | public void testTransaction(){ 50 | User user = new User(); 51 | user.setName("jboost"); 52 | user.setGender(User.Gender.M); 53 | try { 54 | userService.createWithTransaction(user); 55 | }catch (Exception e){ 56 | e.printStackTrace(); 57 | } 58 | Assert.assertNotNull(userService.selectByPk(user.getId())); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /springboot-usingstarter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.5.RELEASE 9 | 10 | 11 | cn.jboost.springboot 12 | springboot-usingstarter 13 | 1.0.0-SNAPSHOT 14 | springboot-usingstarter 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | cn.jboost.springboot 24 | springboot-starter 25 | 1.0.0-SNAPSHOT 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-test 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-maven-plugin 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /springboot-usingstarter/src/main/java/cn/jboost/springboot/usingstarter/SpringbootUsingstarterApplication.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.usingstarter; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootUsingstarterApplication { 8 | 9 | public static void main(String[] args) { 10 | 11 | SpringApplication.run(SpringbootUsingstarterApplication.class, args); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /springboot-usingstarter/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | my.disable=false 2 | my.name=jboost 3 | my.website=blog.jboost.cn 4 | -------------------------------------------------------------------------------- /springboot-usingstarter/src/test/java/cn/jboost/springboot/usingstarter/SpringbootUsingstarterApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.jboost.springboot.usingstarter; 2 | 3 | import cn.jboost.springboot.starter.MyService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | @RunWith(SpringRunner.class) 11 | @SpringBootTest 12 | public class SpringbootUsingstarterApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | @Autowired 19 | private MyService myService; 20 | 21 | @Test 22 | public void testStarter(){ 23 | System.out.printf(myService.sayHi()); 24 | } 25 | 26 | } 27 | --------------------------------------------------------------------------------