Repository: dyc87112/SpringBoot-Learning Branch: master Commit: 4212d163da81 Files: 714 Total size: 743.5 KB Directory structure: gitextract_o44g23q_/ ├── .gitignore ├── .gitmodules ├── 1.x/ │ ├── Chapter1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Chapter1Application.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── Chapter1ApplicationTests.java │ ├── Chapter2-1-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── service/ │ │ │ │ │ └── BlogProperties.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application-dev.properties │ │ │ ├── application-prod.properties │ │ │ ├── application-test.properties │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter2-1-2/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── Application.java │ │ │ ├── ApplicationEnvironmentPreparedEventListener.java │ │ │ ├── ApplicationFailedEventListener.java │ │ │ ├── ApplicationPreparedEventListener.java │ │ │ ├── ApplicationReadyEventListener.java │ │ │ ├── ApplicationStartedEventListener.java │ │ │ └── ApplicationStartingEventListener.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── spring.factories │ │ └── application.properties │ ├── Chapter2-2-1/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── Application.java │ │ │ ├── FooProperties.java │ │ │ └── PostInfo.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter3-1-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── domain/ │ │ │ │ │ └── User.java │ │ │ │ └── web/ │ │ │ │ ├── HelloController.java │ │ │ │ └── UserController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-1-2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ └── index.html │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-1-3/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ └── index.ftl │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-1-4/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ └── index.vm │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-1-5/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── Application.java │ │ │ ├── Swagger2.java │ │ │ ├── domain/ │ │ │ │ └── User.java │ │ │ └── web/ │ │ │ ├── HelloController.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter3-1-6/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── dto/ │ │ │ │ │ └── ErrorInfo.java │ │ │ │ ├── exception/ │ │ │ │ │ ├── GlobalExceptionHandler.java │ │ │ │ │ └── MyException.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ ├── error.html │ │ │ └── index.html │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-1-7/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── Application.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter3-1-8/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── Application.java │ │ │ └── web/ │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter3-2-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── service/ │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-10/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── Person.java │ │ │ │ └── PersonRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── ApplicationTests.java │ │ └── resources/ │ │ ├── application.properties │ │ └── ldap-server.ldif │ ├── Chapter3-2-11/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-3/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── DataSourceConfig.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-4/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── DataSourceConfig.java │ │ │ │ ├── PrimaryConfig.java │ │ │ │ ├── SecondaryConfig.java │ │ │ │ └── domain/ │ │ │ │ ├── p/ │ │ │ │ │ ├── User.java │ │ │ │ │ └── UserRepository.java │ │ │ │ └── s/ │ │ │ │ ├── Message.java │ │ │ │ └── MessageRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-5/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── RedisConfig.java │ │ │ │ ├── RedisObjectSerializer.java │ │ │ │ └── domain/ │ │ │ │ └── User.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-6/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-7/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserMapper.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-8/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserMapper.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-2-9/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── service/ │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── db/ │ │ │ └── V1__Base_version.sql │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter3-3-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── domain/ │ │ │ │ │ ├── User.java │ │ │ │ │ └── UserRepository.java │ │ │ │ └── service/ │ │ │ │ └── UserService.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-1-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── task/ │ │ │ │ └── ScheduledTasks.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-1-2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── async/ │ │ │ │ └── Task.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-1-3/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── async/ │ │ │ │ └── Task.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-1-4/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── async/ │ │ │ │ └── Task.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-1-5/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── async/ │ │ │ │ └── Task.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-2-2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── log4j.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-2-3/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ ├── application-dev.properties │ │ │ ├── application-prod.properties │ │ │ ├── application-test.properties │ │ │ ├── application.properties │ │ │ └── log4j.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-2-4/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── aspect/ │ │ │ │ │ └── WebLogAspect.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── log4j.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-2-5/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── aspect/ │ │ │ │ │ └── WebLogAspect.java │ │ │ │ ├── log/ │ │ │ │ │ └── MongoAppender.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── log4j.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-2-6/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── DemoApplication.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── DemoApplicationTests.java │ ├── Chapter4-3-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ ├── WebSecurityConfig.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ ├── hello.html │ │ │ ├── index.html │ │ │ └── login.html │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-4-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── ehcache.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-4-2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter4-5-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ └── template.vm │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter5-2-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── HelloApplication.java │ │ │ │ └── rabbit/ │ │ │ │ ├── RabbitConfig.java │ │ │ │ ├── Receiver.java │ │ │ │ └── Sender.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── HelloApplicationTests.java │ ├── Chapter6-1-1/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── Application.java │ │ │ ├── EventConfig.java │ │ │ ├── Events.java │ │ │ ├── StateMachineConfig.java │ │ │ └── States.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter6-2-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── web/ │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter9-1-1/ │ │ ├── compute-service/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── didispace/ │ │ │ │ │ ├── ComputeServiceApplication.java │ │ │ │ │ └── web/ │ │ │ │ │ └── ComputeController.java │ │ │ │ └── resources/ │ │ │ │ └── application.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── ApplicationTests.java │ │ └── eureka-server/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── Application.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter9-1-2/ │ │ ├── eureka-feign/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── FeignApplication.java │ │ │ │ ├── service/ │ │ │ │ │ └── ComputeClient.java │ │ │ │ └── web/ │ │ │ │ └── ConsumerController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── eureka-ribbon/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── RibbonApplication.java │ │ │ └── web/ │ │ │ └── ConsumerController.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter9-1-3/ │ │ ├── compute-service/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── didispace/ │ │ │ │ │ ├── ComputeServiceApplication.java │ │ │ │ │ └── web/ │ │ │ │ │ └── ComputeController.java │ │ │ │ └── resources/ │ │ │ │ └── application.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── ApplicationTests.java │ │ ├── eureka-feign/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── FeignApplication.java │ │ │ ├── service/ │ │ │ │ ├── ComputeClient.java │ │ │ │ └── ComputeClientHystrix.java │ │ │ └── web/ │ │ │ └── ConsumerController.java │ │ ├── eureka-ribbon/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ ├── RibbonApplication.java │ │ │ ├── service/ │ │ │ │ └── ComputeService.java │ │ │ └── web/ │ │ │ └── ConsumerController.java │ │ └── eureka-server/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── Application.java │ │ └── resources/ │ │ └── application.properties │ ├── Chapter9-1-4/ │ │ ├── config-client/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── web/ │ │ │ │ └── TestController.java │ │ │ └── resources/ │ │ │ └── bootstrap.properties │ │ ├── config-repo/ │ │ │ ├── didispace-dev.properties │ │ │ ├── didispace-prod.properties │ │ │ ├── didispace-test.properties │ │ │ └── didispace.properties │ │ └── config-server/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── Application.java │ │ └── resources/ │ │ ├── application.properties │ │ ├── didispace-dev.properties │ │ ├── didispace-prod.properties │ │ ├── didispace-test.properties │ │ └── didispace.properties │ ├── Chapter9-1-5/ │ │ ├── api-gateway/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── filter/ │ │ │ │ └── AccessFilter.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ ├── eureka-server/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ ├── service-A/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── didispace/ │ │ │ │ │ ├── ComputeServiceApplication.java │ │ │ │ │ └── web/ │ │ │ │ │ └── ComputeController.java │ │ │ │ └── resources/ │ │ │ │ └── application.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── ApplicationTests.java │ │ └── service-B/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── ComputeServiceApplication.java │ │ │ │ └── web/ │ │ │ │ └── ComputeController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter9-2-1/ │ │ ├── compute-service/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── didispace/ │ │ │ │ │ ├── Application.java │ │ │ │ │ └── service/ │ │ │ │ │ ├── ComputeService.java │ │ │ │ │ └── impl/ │ │ │ │ │ └── ComputeServiceImpl.java │ │ │ │ └── resources/ │ │ │ │ ├── application.properties │ │ │ │ └── dubbo.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── ApplicationTests.java │ │ └── consumer/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ ├── Application.java │ │ │ │ └── service/ │ │ │ │ └── ComputeService.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── dubbo.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── Chapter9-2-2/ │ │ ├── compute-service/ │ │ │ ├── compute-api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── service/ │ │ │ │ ├── ComputeService.java │ │ │ │ └── impl/ │ │ │ │ └── ComputeServiceImpl.java │ │ │ ├── compute-api-server/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── didispace/ │ │ │ │ │ │ ├── Application.java │ │ │ │ │ │ └── service/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ └── ComputeServiceImpl.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── application.properties │ │ │ │ │ └── dubbo.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── ApplicationTests.java │ │ │ └── pom.xml │ │ └── consumer/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── dubbo.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── ApplicationTests.java │ ├── README.md │ └── README_zh.md ├── 2.x/ │ ├── README.md │ ├── README_zh.md │ ├── chapter1-1/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter11/ │ │ │ │ ├── Chapter11Application.java │ │ │ │ └── HelloController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter11/ │ │ └── Chapter11ApplicationTests.java │ ├── chapter1-2/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter12/ │ │ │ └── Chapter12Application.java │ │ └── resources/ │ │ └── application.yaml │ ├── chapter1-3/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter13/ │ │ │ └── Chapter13Application.java │ │ └── resources/ │ │ └── application.yaml │ ├── chapter1-4/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter14/ │ │ │ ├── Chapter14Application.java │ │ │ ├── DidiProperties.java │ │ │ └── HelloController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter1-5/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter15/ │ │ │ │ └── Chapter15Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter15/ │ │ └── PropertiesTest.java │ ├── chapter2-1/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter21/ │ │ │ │ ├── Chapter21Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter21/ │ │ └── Chapter21ApplicationTests.java │ ├── chapter2-2/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter22/ │ │ │ ├── Chapter22Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter2-3/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter23/ │ │ │ ├── Chapter23Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter2-4/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter24/ │ │ │ ├── Chapter24Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter2-5/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── docs/ │ │ │ ├── asciidoc/ │ │ │ │ ├── generated/ │ │ │ │ │ ├── definitions.adoc │ │ │ │ │ ├── overview.adoc │ │ │ │ │ ├── paths.adoc │ │ │ │ │ └── security.adoc │ │ │ │ ├── generated-by-plugin/ │ │ │ │ │ ├── definitions.adoc │ │ │ │ │ ├── overview.adoc │ │ │ │ │ ├── paths.adoc │ │ │ │ │ └── security.adoc │ │ │ │ └── html/ │ │ │ │ ├── definitions.html │ │ │ │ ├── overview.html │ │ │ │ ├── paths.html │ │ │ │ └── security.html │ │ │ ├── confluence/ │ │ │ │ └── generated/ │ │ │ │ ├── definitions.txt │ │ │ │ ├── overview.txt │ │ │ │ ├── paths.txt │ │ │ │ └── security.txt │ │ │ └── markdown/ │ │ │ └── generated/ │ │ │ ├── definitions.md │ │ │ ├── overview.md │ │ │ ├── paths.md │ │ │ └── security.md │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter25/ │ │ │ │ ├── Chapter25Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserController.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter25/ │ │ └── DemoApplicationTests.java │ ├── chapter2-6/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter26/ │ │ │ ├── Chapter26Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter2-7/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter27/ │ │ │ ├── Chapter27Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter2-8/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter28/ │ │ │ ├── Chapter28Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter2-9/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter29/ │ │ │ ├── Chapter29Application.java │ │ │ ├── User.java │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter3-1/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter31/ │ │ │ │ ├── Chapter31Application.java │ │ │ │ ├── User.java │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter31/ │ │ └── Chapter31ApplicationTests.java │ ├── chapter3-10/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter310/ │ │ │ │ ├── Chapter310Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter310/ │ │ └── Chapter310ApplicationTests.java │ ├── chapter3-11/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter311/ │ │ │ │ ├── Chapter311Application.java │ │ │ │ ├── User.java │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── db/ │ │ │ └── migration/ │ │ │ ├── V1_1__alter_table_user.sql │ │ │ └── V1__Base_version.sql │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter311/ │ │ └── Chapter311ApplicationTests.java │ ├── chapter3-12/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter312/ │ │ │ │ ├── Chapter312Application.java │ │ │ │ ├── DataSourceConfiguration.java │ │ │ │ └── TestService.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter312/ │ │ └── Chapter312ApplicationTests.java │ ├── chapter3-13/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter313/ │ │ │ │ └── Chapter313Application.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── schema-all.sql │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter31/ │ │ └── Chapter31ApplicationTests.java │ ├── chapter3-2/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter32/ │ │ │ │ ├── Chapter32Application.java │ │ │ │ ├── User.java │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter32/ │ │ └── Chapter32ApplicationTests.java │ ├── chapter3-3/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter33/ │ │ │ │ ├── Chapter33Application.java │ │ │ │ ├── User.java │ │ │ │ ├── UserController.java │ │ │ │ ├── UserService.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter33/ │ │ └── Chapter33ApplicationTests.java │ ├── chapter3-4/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter34/ │ │ │ │ ├── Chapter34Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter34/ │ │ └── Chapter34ApplicationTests.java │ ├── chapter3-5/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter35/ │ │ │ │ ├── Chapter35Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserMapper.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter35/ │ │ └── Chapter35ApplicationTests.java │ ├── chapter3-6/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter36/ │ │ │ │ ├── Chapter36Application.java │ │ │ │ ├── entity/ │ │ │ │ │ └── User.java │ │ │ │ └── mapper/ │ │ │ │ └── UserMapper.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── mapper/ │ │ │ └── UserMapper.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter36/ │ │ └── Chapter36ApplicationTests.java │ ├── chapter3-7/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter37/ │ │ │ │ ├── Chapter37Application.java │ │ │ │ └── DataSourceConfiguration.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter37/ │ │ └── Chapter37ApplicationTests.java │ ├── chapter3-8/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter38/ │ │ │ │ ├── Chapter38Application.java │ │ │ │ ├── DataSourceConfiguration.java │ │ │ │ ├── PrimaryConfig.java │ │ │ │ ├── SecondaryConfig.java │ │ │ │ ├── p/ │ │ │ │ │ ├── User.java │ │ │ │ │ └── UserRepository.java │ │ │ │ └── s/ │ │ │ │ ├── Message.java │ │ │ │ └── MessageRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter38/ │ │ └── Chapter38ApplicationTests.java │ ├── chapter3-9/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter39/ │ │ │ │ ├── Chapter39Application.java │ │ │ │ ├── DataSourceConfiguration.java │ │ │ │ ├── PrimaryConfig.java │ │ │ │ ├── SecondaryConfig.java │ │ │ │ ├── p/ │ │ │ │ │ ├── entity/ │ │ │ │ │ │ └── UserPrimary.java │ │ │ │ │ └── mapper/ │ │ │ │ │ └── UserMapperPrimary.java │ │ │ │ └── s/ │ │ │ │ ├── entity/ │ │ │ │ │ └── UserSecondary.java │ │ │ │ └── mapper/ │ │ │ │ └── UserMapperSecondary.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ ├── mapper.primary/ │ │ │ │ └── UserMapper.xml │ │ │ └── mapper.secondary/ │ │ │ └── UserMapper.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter39/ │ │ └── Chapter39ApplicationTests.java │ ├── chapter4-1/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter41/ │ │ │ ├── Chapter41Application.java │ │ │ └── HelloController.java │ │ └── resources/ │ │ ├── application.properties │ │ └── templates/ │ │ └── index.html │ ├── chapter4-2/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter42/ │ │ │ ├── Chapter42Application.java │ │ │ └── HelloController.java │ │ └── resources/ │ │ ├── application.properties │ │ └── templates/ │ │ └── index.html │ ├── chapter4-3/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter43/ │ │ │ │ ├── Chapter43Application.java │ │ │ │ └── UploadController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ └── upload.html │ │ └── test/ │ │ └── java/ │ │ └── FileTest.java │ ├── chapter4-4/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter44/ │ │ │ │ ├── Chapter44Application.java │ │ │ │ └── UploadController.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── templates/ │ │ │ └── upload.html │ │ └── test/ │ │ └── java/ │ │ └── FileTest.java │ ├── chapter4-5/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter45/ │ │ │ ├── Application.java │ │ │ ├── HelloController.java │ │ │ └── WebSecurityConfig.java │ │ └── resources/ │ │ ├── application.properties │ │ └── templates/ │ │ ├── hello.html │ │ ├── index.html │ │ └── login.html │ ├── chapter5-1/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter51/ │ │ │ │ ├── Chapter51Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter51/ │ │ └── Chapter51ApplicationTests.java │ ├── chapter5-2/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter52/ │ │ │ │ ├── Chapter52Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── ehcache.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter52/ │ │ └── Chapter52ApplicationTests.java │ ├── chapter5-3/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter53/ │ │ │ │ ├── Chapter53Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ ├── ehcache-1.xml │ │ │ └── ehcache-2.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter53/ │ │ └── Chapter53ApplicationTests.java │ ├── chapter5-4/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter54/ │ │ │ │ ├── Chapter54Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter54/ │ │ └── Chapter54ApplicationTests.java │ ├── chapter5-5/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter55/ │ │ │ └── Chapter55Application.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter6-1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter61/ │ │ │ │ ├── Chapter61Application.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter61/ │ │ └── ApplicationTests.java │ ├── chapter6-2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter62/ │ │ │ │ ├── Chapter62Application.java │ │ │ │ ├── Person.java │ │ │ │ └── PersonRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter62/ │ │ │ └── ApplicationTests.java │ │ └── resources/ │ │ ├── application.properties │ │ └── ldap-server.ldif │ ├── chapter6-3/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter63/ │ │ │ │ ├── Chapter63Application.java │ │ │ │ └── Monitor.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter63/ │ │ └── ApplicationTests.java │ ├── chapter6-4/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter64/ │ │ │ │ ├── Chapter64Application.java │ │ │ │ ├── UserInfo.java │ │ │ │ └── UserInfoRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter64/ │ │ └── ApplicationTests.java │ ├── chapter7-1/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter71/ │ │ │ ├── Chapter71Application.java │ │ │ └── ScheduledTasks.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter7-2/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter72/ │ │ │ ├── Chapter72Application.java │ │ │ └── MySimpleJob.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter7-3/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter73/ │ │ │ ├── Chapter73Application.java │ │ │ └── MyShardingJob.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter7-4/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter74/ │ │ │ ├── Chapter74Application.java │ │ │ └── MySimpleJob.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter7-5/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter75/ │ │ │ │ ├── AsyncTasks.java │ │ │ │ └── Chapter75Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter75/ │ │ └── Chapter75ApplicationTests.java │ ├── chapter7-6/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter76/ │ │ │ │ ├── AsyncTasks.java │ │ │ │ └── Chapter76Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter76/ │ │ └── Chapter76ApplicationTests.java │ ├── chapter7-7/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter77/ │ │ │ │ ├── AsyncTasks.java │ │ │ │ └── Chapter77Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter77/ │ │ └── Chapter77ApplicationTests.java │ ├── chapter7-8/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── didispace/ │ │ │ │ └── chapter78/ │ │ │ │ ├── AsyncTasks.java │ │ │ │ └── Chapter78Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── didispace/ │ │ └── chapter78/ │ │ └── Chapter78ApplicationTests.java │ ├── chapter8-1/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter81/ │ │ │ └── Chapter81Application.java │ │ └── resources/ │ │ └── application.properties │ ├── chapter8-2/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter82/ │ │ │ └── Chapter82Application.java │ │ └── resources/ │ │ ├── application.properties │ │ └── log4j2.xml │ ├── chapter8-3/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── didispace/ │ │ │ └── chapter83/ │ │ │ └── Chapter83Application.java │ │ └── resources/ │ │ ├── application.properties │ │ └── tinylog.properties │ └── pom.xml ├── README.md ├── README_zh.md └── pom.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .class .classpath .project build bin .bak .settings Thumbs.db .DS_Store ._.DS_Store logs target *.iml .idea ================================================ FILE: .gitmodules ================================================ ================================================ FILE: 1.x/Chapter1/pom.xml ================================================ 4.0.0 com.didispace Chapter1 1.0.0 jar Chapter1 The first Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter1/src/main/java/com/didispace/Chapter1Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter1Application { public static void main(String[] args) { SpringApplication.run(Chapter1Application.class, args); } } ================================================ FILE: 1.x/Chapter1/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } } ================================================ FILE: 1.x/Chapter1/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter1/src/test/java/com/didispace/Chapter1ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.HelloController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class Chapter1ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter2-1-1/pom.xml ================================================ 4.0.0 com.didispace Chapter2-1-1 1.0.0 jar Chapter2-1-1 org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter2-1-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter2-1-1/src/main/java/com/didispace/service/BlogProperties.java ================================================ package com.didispace.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/5 下午12:16. * @blog http://blog.didispace.com */ @Component public class BlogProperties { @Value("${com.didispace.blog.name}") private String name; @Value("${com.didispace.blog.title}") private String title; @Value("${com.didispace.blog.desc}") private String desc; @Value("${com.didispace.blog.value}") private String value; @Value("${com.didispace.blog.number}") private Integer number; @Value("${com.didispace.blog.bignumber}") private Long bignumber; @Value("${com.didispace.blog.test1}") private Integer test1; @Value("${com.didispace.blog.test2}") private Integer test2; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; } public Long getBignumber() { return bignumber; } public void setBignumber(Long bignumber) { this.bignumber = bignumber; } public Integer getTest1() { return test1; } public void setTest1(Integer test1) { this.test1 = test1; } public Integer getTest2() { return test2; } public void setTest2(Integer test2) { this.test2 = test2; } } ================================================ FILE: 1.x/Chapter2-1-1/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } } ================================================ FILE: 1.x/Chapter2-1-1/src/main/resources/application-dev.properties ================================================ # 服务端口 server.port=1111 ================================================ FILE: 1.x/Chapter2-1-1/src/main/resources/application-prod.properties ================================================ # 服务端口 server.port=3333 ================================================ FILE: 1.x/Chapter2-1-1/src/main/resources/application-test.properties ================================================ # 服务端口 server.port=2222 ================================================ FILE: 1.x/Chapter2-1-1/src/main/resources/application.properties ================================================ com.didispace.blog.name=程序猿DD com.didispace.blog.title=Spring Boot教程 com.didispace.blog.desc=${com.didispace.blog.name}正在努力写《${com.didispace.blog.title}》 # 随机字符串 com.didispace.blog.value=${random.value} # 随机int com.didispace.blog.number=${random.int} # 随机long com.didispace.blog.bignumber=${random.long} # 10以内的随机数 com.didispace.blog.test1=${random.int(10)} # 10-20的随机数 com.didispace.blog.test2=${random.int[10,20]} # 多环境配置文件激活属性 spring.profiles.active=dev ================================================ FILE: 1.x/Chapter2-1-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.service.BlogProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { private static final Log log = LogFactory.getLog(ApplicationTests.class); @Autowired private BlogProperties blogProperties; @Test public void test1() throws Exception { Assert.assertEquals("程序猿DD", blogProperties.getName()); Assert.assertEquals("Spring Boot教程", blogProperties.getTitle()); Assert.assertEquals("程序猿DD正在努力写《Spring Boot教程》", blogProperties.getDesc()); log.info("随机数测试输出:"); log.info("随机字符串 : " + blogProperties.getValue()); log.info("随机int : " + blogProperties.getNumber()); log.info("随机long : " + blogProperties.getBignumber()); log.info("随机10以下 : " + blogProperties.getTest1()); log.info("随机10-20 : " + blogProperties.getTest2()); } } ================================================ FILE: 1.x/Chapter2-1-2/pom.xml ================================================ 4.0.0 com.didispace Chapter2-1-2 1.0.0 jar Chapter2-1-2 Spring Boot 2.0 features : Application Events and Listeners org.springframework.boot spring-boot-starter-parent 2.0.0.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.projectlombok lombok provided org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @Slf4j @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public DataLoader dataLoader() { return new DataLoader(); } @Slf4j static class DataLoader implements CommandLineRunner { @Override public void run(String... strings) throws Exception { log.info("Loading data..."); } } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationEnvironmentPreparedEventListener.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.context.ApplicationListener; @Slf4j public class ApplicationEnvironmentPreparedEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { log.info("......ApplicationEnvironmentPreparedEvent......"); } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationFailedEventListener.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.context.ApplicationListener; @Slf4j public class ApplicationFailedEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationFailedEvent event) { log.info("......ApplicationFailedEvent......"); } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationPreparedEventListener.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.context.ApplicationListener; @Slf4j public class ApplicationPreparedEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationPreparedEvent event) { log.info("......ApplicationPreparedEvent......"); } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationReadyEventListener.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; @Slf4j public class ApplicationReadyEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationReadyEvent event) { log.info("......ApplicationReadyEvent......"); } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartedEventListener.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; @Slf4j public class ApplicationStartedEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationStartedEvent event) { log.info("......ApplicationStartedEvent......"); } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartingEventListener.java ================================================ package com.didispace; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.event.ApplicationStartingEvent; import org.springframework.context.ApplicationListener; @Slf4j public class ApplicationStartingEventListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationStartingEvent event) { log.info("......ApplicationStartingEvent......"); } } ================================================ FILE: 1.x/Chapter2-1-2/src/main/resources/META-INF/spring.factories ================================================ org.springframework.context.ApplicationListener=com.didispace.ApplicationEnvironmentPreparedEventListener,\ com.didispace.ApplicationFailedEventListener,\ com.didispace.ApplicationPreparedEventListener,\ com.didispace.ApplicationReadyEventListener,\ com.didispace.ApplicationStartedEventListener,\ com.didispace.ApplicationStartingEventListener ================================================ FILE: 1.x/Chapter2-1-2/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter2-2-1/pom.xml ================================================ 4.0.0 com.didispace Chapter2-2-1 1.0.0 jar Chapter2-2-1 Spring Boot 2 : Relaxed Binding org.springframework.boot spring-boot-starter-parent 2.0.0.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.projectlombok lombok 1.16.20 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter2-2-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.ApplicationContext; import java.util.List; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(Application.class, args); Binder binder = Binder.get(context.getEnvironment()); // 绑定简单配置 FooProperties foo = binder.bind("com.didispace", Bindable.of(FooProperties.class)).get(); System.out.println(foo.getFoo()); // 绑定List配置 List post = binder.bind("com.didispace.post", Bindable.listOf(String.class)).get(); System.out.println(post); List posts = binder.bind("com.didispace.posts", Bindable.listOf(PostInfo.class)).get(); System.out.println(posts); // 读取配置 System.out.println(context.getEnvironment().containsProperty("com.didispace.database-platform")); System.out.println(context.getEnvironment().containsProperty("com.didispace.databasePlatform")); } } ================================================ FILE: 1.x/Chapter2-2-1/src/main/java/com/didispace/FooProperties.java ================================================ package com.didispace; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @Data @ConfigurationProperties(prefix = "com.didispace") public class FooProperties { private String foo; private String databasePlatform; } ================================================ FILE: 1.x/Chapter2-2-1/src/main/java/com/didispace/PostInfo.java ================================================ package com.didispace; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @Data @ConfigurationProperties public class PostInfo { private String title; private String content; } ================================================ FILE: 1.x/Chapter2-2-1/src/main/resources/application.properties ================================================ com.didispace.foo=bar com.didispace.database-platform=sql com.didispace.post[0]=Why Spring Boot com.didispace.post[1]=Why Spring Cloud com.didispace.posts[0].title=Why Spring Boot com.didispace.posts[0].content=It is perfect! com.didispace.posts[1].title=Why Spring Cloud com.didispace.posts[1].content=It is perfect too! ================================================ FILE: 1.x/Chapter3-1-1/pom.xml ================================================ 4.0.0 com.didispace Chapter3-1-1 1.0.0 jar Chapter3-1-1 RESTful API Project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-1-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-1/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ public class User { private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-1-1/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } } ================================================ FILE: 1.x/Chapter3-1-1/src/main/java/com/didispace/web/UserController.java ================================================ package com.didispace.web; import com.didispace.domain.User; import java.util.*; import org.springframework.web.bind.annotation.*; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RestController @RequestMapping(value="/users") // 通过这里配置使下面的映射都在/users下,可去除 public class UserController { static Map users = Collections.synchronizedMap(new HashMap()); @RequestMapping(value="/", method=RequestMethod.GET) public List getUserList() { // 处理"/users/"的GET请求,用来获取用户列表 // 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递 List r = new ArrayList(users.values()); return r; } @RequestMapping(value="/", method=RequestMethod.POST) public String postUser(@ModelAttribute User user) { // 处理"/users/"的POST请求,用来创建User // 除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数 users.put(user.getId(), user); return "success"; } @RequestMapping(value="/{id}", method=RequestMethod.GET) public User getUser(@PathVariable Long id) { // 处理"/users/{id}"的GET请求,用来获取url中id值的User信息 // url中的id可通过@PathVariable绑定到函数的参数中 return users.get(id); } @RequestMapping(value="/{id}", method=RequestMethod.PUT) public String putUser(@PathVariable Long id, @ModelAttribute User user) { // 处理"/users/{id}"的PUT请求,用来更新User信息 User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @RequestMapping(value="/{id}", method=RequestMethod.DELETE) public String deleteUser(@PathVariable Long id) { // 处理"/users/{id}"的DELETE请求,用来删除User users.remove(id); return "success"; } } ================================================ FILE: 1.x/Chapter3-1-1/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.web.HelloController; import com.didispace.web.UserController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup( new HelloController(), new UserController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } @Test public void testUserController() throws Exception { // 测试UserController RequestBuilder request = null; // 1、get查一下user列表,应该为空 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[]"))); // 2、post提交一个user request = post("/users/") .param("id", "1") .param("name", "测试大师") .param("age", "20"); mvc.perform(request) // .andDo(MockMvcResultHandlers.print()) .andExpect(content().string(equalTo("success"))); // 3、get获取user列表,应该有刚才插入的数据 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[{\"id\":1,\"name\":\"测试大师\",\"age\":20}]"))); // 4、put修改id为1的user request = put("/users/1") .param("name", "测试终极大师") .param("age", "30"); mvc.perform(request) .andExpect(content().string(equalTo("success"))); // 5、get一个id为1的user request = get("/users/1"); mvc.perform(request) .andExpect(content().string(equalTo("{\"id\":1,\"name\":\"测试终极大师\",\"age\":30}"))); // 6、del删除id为1的user request = delete("/users/1"); mvc.perform(request) .andExpect(content().string(equalTo("success"))); // 7、get查一下user列表,应该为空 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[]"))); } } ================================================ FILE: 1.x/Chapter3-1-2/pom.xml ================================================ 4.0.0 com.didispace Chapter3-1-2 1.0.0 jar Chapter3-1-2 Spring Boot with Thymeleaf org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 1.x/Chapter3-1-2/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-2/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class HelloController { @ResponseBody @RequestMapping("/hello") public String hello() { return "Hello World"; } @RequestMapping("/") public String index(ModelMap map) { map.addAttribute("host", "http://blog.didispace.com"); return "index"; } } ================================================ FILE: 1.x/Chapter3-1-2/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-2/src/main/resources/templates/index.html ================================================

Hello World

================================================ FILE: 1.x/Chapter3-1-2/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.HelloController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup( new HelloController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter3-1-3/pom.xml ================================================ 4.0.0 com.didispace demo 1.0.0 jar demo Spring Boot Web project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-freemarker org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 1.x/Chapter3-1-3/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-3/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class HelloController { @RequestMapping("/hello") @ResponseBody public String hello() { return "Hello World"; } @RequestMapping("/") public String index(ModelMap map) { map.addAttribute("host", "http://blog.didispace.com"); return "index"; } } ================================================ FILE: 1.x/Chapter3-1-3/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-3/src/main/resources/templates/index.ftl ================================================ FreeMarker模板引擎

${host}

================================================ FILE: 1.x/Chapter3-1-3/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.HelloController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup( new HelloController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter3-1-4/pom.xml ================================================ 4.0.0 com.didispace demo 1.0.0 jar demo Spring Boot Web project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-velocity org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 1.x/Chapter3-1-4/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-4/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class HelloController { @RequestMapping("/hello") @ResponseBody public String hello() { return "Hello World"; } @RequestMapping("/") public String index(ModelMap map) { map.addAttribute("host", "http://blog.didispace.com"); return "index"; } } ================================================ FILE: 1.x/Chapter3-1-4/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-4/src/main/resources/templates/index.vm ================================================ Velocity模板

${host}

================================================ FILE: 1.x/Chapter3-1-4/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.HelloController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup( new HelloController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter3-1-5/pom.xml ================================================ 4.0.0 com.didispace SpringBootWithSwagger 1.0.0 jar SpringBootWithSwagger SpringBootWithSwagger org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web io.springfox springfox-swagger2 2.2.2 io.springfox springfox-swagger-ui 2.2.2 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-1-5/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-5/src/main/java/com/didispace/Swagger2.java ================================================ package com.didispace; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * @author 程序猿DD * @version 1.0.0 * @date 16/4/18 下午12:02. * @blog http://blog.didispace.com */ @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.didispace.web")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2构建RESTful APIs") .description("更多Spring Boot相关文章请关注:http://blog.didispace.com/") .termsOfServiceUrl("http://blog.didispace.com/") .contact("程序猿DD") .version("1.0") .build(); } } ================================================ FILE: 1.x/Chapter3-1-5/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ public class User { private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-1-5/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import springfox.documentation.annotations.ApiIgnore; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RestController public class HelloController { @ApiIgnore @RequestMapping(value = "/hello", method = RequestMethod.GET) public String index() { return "Hello World"; } } ================================================ FILE: 1.x/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java ================================================ package com.didispace.web; import com.didispace.domain.User; import java.util.*; import io.swagger.annotations.*; import org.springframework.web.bind.annotation.*; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RestController @RequestMapping(value="/users") // 通过这里配置使下面的映射都在/users下,可去除 public class UserController { static Map users = Collections.synchronizedMap(new HashMap()); @ApiOperation(value="获取用户列表", notes="") @RequestMapping(value={""}, method=RequestMethod.GET) public List getUserList() { List r = new ArrayList(users.values()); return r; } @ApiOperation(value="创建用户", notes="根据User对象创建用户") @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") @RequestMapping(value="", method=RequestMethod.POST) public String postUser(@RequestBody User user) { users.put(user.getId(), user); return "success"; } @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path") @RequestMapping(value="/{id}", method=RequestMethod.GET) public User getUser(@PathVariable Long id) { return users.get(id); } @ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") @ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path"), @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") }) @RequestMapping(value="/{id}", method=RequestMethod.PUT) public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @ApiOperation(value="删除用户", notes="根据url的id来指定删除对象") @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path") @RequestMapping(value="/{id}", method=RequestMethod.DELETE) public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 1.x/Chapter3-1-5/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-6/pom.xml ================================================ 4.0.0 com.didispace Chapter3-1-6 1.0.0 jar Chapter3-1-6 Spring Boot org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 1.x/Chapter3-1-6/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-6/src/main/java/com/didispace/dto/ErrorInfo.java ================================================ package com.didispace.dto; public class ErrorInfo { public static final Integer OK = 0; public static final Integer ERROR = 100; private Integer code; private String message; private String url; private T data; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public static Integer getOK() { return OK; } public static Integer getERROR() { return ERROR; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } } ================================================ FILE: 1.x/Chapter3-1-6/src/main/java/com/didispace/exception/GlobalExceptionHandler.java ================================================ package com.didispace.exception; import com.didispace.dto.ErrorInfo; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = Exception.class) public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { ModelAndView mav = new ModelAndView(); mav.addObject("exception", e); mav.addObject("url", req.getRequestURL()); mav.setViewName("error"); return mav; } @ExceptionHandler(value = MyException.class) @ResponseBody public ErrorInfo jsonErrorHandler(HttpServletRequest req, MyException e) throws Exception { ErrorInfo r = new ErrorInfo<>(); r.setMessage(e.getMessage()); r.setCode(ErrorInfo.ERROR); r.setData("Some Data"); r.setUrl(req.getRequestURL().toString()); return r; } } ================================================ FILE: 1.x/Chapter3-1-6/src/main/java/com/didispace/exception/MyException.java ================================================ package com.didispace.exception; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/2 上午10:50. * @blog http://blog.didispace.com */ public class MyException extends Exception { public MyException(String message) { super(message); } } ================================================ FILE: 1.x/Chapter3-1-6/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import com.didispace.exception.MyException; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class HelloController { @RequestMapping("/hello") public String hello() throws Exception { throw new Exception("发生错误"); } @RequestMapping("/json") public String json() throws MyException { throw new MyException("发生错误2"); } @RequestMapping("/") public String index(ModelMap map) { map.addAttribute("host", "http://blog.didispace.com"); return "index"; } } ================================================ FILE: 1.x/Chapter3-1-6/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-6/src/main/resources/templates/error.html ================================================ 统一异常处理

Error Handler

================================================ FILE: 1.x/Chapter3-1-6/src/main/resources/templates/index.html ================================================

Hello World

================================================ FILE: 1.x/Chapter3-1-6/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.HelloController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { } ================================================ FILE: 1.x/Chapter3-1-7/pom.xml ================================================ 4.0.0 com.didispace Chapter3-1-7 1.0.0 jar Chapter3-1-7 Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web com.fasterxml.jackson.datatype jackson-datatype-jsr310 org.projectlombok lombok 1.16.20 org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 1.x/Chapter3-1-7/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @RestController class HelloController { @PostMapping("/user") public UserDto user(@RequestBody UserDto userDto) throws Exception { return userDto; } } @Data @NoArgsConstructor @AllArgsConstructor static class UserDto { private String userName; private LocalDate birthday; } @Bean public ObjectMapper serializingObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.registerModule(new JavaTimeModule()); return objectMapper; } } ================================================ FILE: 1.x/Chapter3-1-7/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-1-8/pom.xml ================================================ 4.0.0 com.didispace Chapter3-1-8 1.0.0 jar org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web com.fasterxml.jackson.dataformat jackson-dataformat-xml org.projectlombok lombok org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-1-8/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-1-8/src/main/java/com/didispace/web/User.java ================================================ package com.didispace.web; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @Data @NoArgsConstructor @AllArgsConstructor @JacksonXmlRootElement(localName = "User") public class User { @JacksonXmlProperty(localName = "name") private String name; @JacksonXmlProperty(localName = "age") private Integer age; } ================================================ FILE: 1.x/Chapter3-1-8/src/main/java/com/didispace/web/UserController.java ================================================ package com.didispace.web; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class UserController { @PostMapping(value = "/user", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE) @ResponseBody public User create(@RequestBody User user) { user.setName("didispace.com : " + user.getName()); user.setAge(user.getAge() + 100); return user; } } ================================================ FILE: 1.x/Chapter3-1-8/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter3-2-1/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-1 1.0.0 jar Chapter3-2-1 Spring Boot with JDBCTemplate org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserService.java ================================================ package com.didispace.service; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/17 下午7:04. * @blog http://blog.didispace.com */ public interface UserService { /** * 新增一个用户 * @param name * @param age */ void create(String name, Integer age); /** * 根据name删除一个用户高 * @param name */ void deleteByName(String name); /** * 获取用户总量 */ Integer getAllUsers(); /** * 删除所有用户 */ void deleteAllUsers(); } ================================================ FILE: 1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserServiceImpl.java ================================================ package com.didispace.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/17 下午6:44. * @blog http://blog.didispace.com */ @Service public class UserServiceImpl implements UserService { @Autowired private JdbcTemplate jdbcTemplate; @Override public void create(String name, Integer age) { jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age); } @Override public void deleteByName(String name) { jdbcTemplate.update("delete from USER where NAME = ?", name); } @Override public Integer getAllUsers() { return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class); } @Override public void deleteAllUsers() { jdbcTemplate.update("delete from USER"); } } ================================================ FILE: 1.x/Chapter3-2-1/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver ================================================ FILE: 1.x/Chapter3-2-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.service.UserService; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserService userSerivce; @Before public void setUp() { // 准备,清空user表 userSerivce.deleteAllUsers(); } @Test public void test() throws Exception { // 插入5个用户 userSerivce.create("a", 1); userSerivce.create("b", 2); userSerivce.create("c", 3); userSerivce.create("d", 4); userSerivce.create("e", 5); // 查数据库,应该有5个用户 Assert.assertEquals(5, userSerivce.getAllUsers().intValue()); // 删除两个用户 userSerivce.deleteByName("a"); userSerivce.deleteByName("e"); // 查数据库,应该有5个用户 Assert.assertEquals(3, userSerivce.getAllUsers().intValue()); } } ================================================ FILE: 1.x/Chapter3-2-10/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-10 1.0.0 jar Chapter3-2-10 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-data-ldap com.unboundid unboundid-ldapsdk test org.springframework.boot spring-boot-starter-test test org.projectlombok lombok 1.16.16 provided org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-10/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-10/src/main/java/com/didispace/Person.java ================================================ package com.didispace; import lombok.Data; import org.springframework.ldap.odm.annotations.*; import javax.naming.Name; @Entry(base = "ou=people,dc=didispace,dc=com", objectClasses = "inetOrgPerson") @Data public class Person { @Id private Name id; @DnAttribute(value = "uid", index = 3) private String uid; @Attribute(name = "cn") private String commonName; @Attribute(name = "sn") private String suerName; private String userPassword; } ================================================ FILE: 1.x/Chapter3-2-10/src/main/java/com/didispace/PersonRepository.java ================================================ package com.didispace; import org.springframework.data.repository.CrudRepository; import javax.naming.Name; public interface PersonRepository extends CrudRepository { } ================================================ FILE: 1.x/Chapter3-2-10/src/main/resources/application.properties ================================================ #spring.ldap.urls=ldap://localhost:1235 #spring.ldap.base=dc=didispace,dc=com #spring.ldap.username=didispace #spring.ldap.password=123456 ================================================ FILE: 1.x/Chapter3-2-10/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { @Autowired private PersonRepository personRepository; @Test public void findAll() throws Exception { personRepository.findAll().forEach(p -> { System.out.println(p); }); } @Test public void save() throws Exception { Person person = new Person(); person.setUid("uid:1"); person.setSuerName("AAA"); person.setCommonName("aaa"); person.setUserPassword("123456"); personRepository.save(person); personRepository.findAll().forEach(p -> { System.out.println(p); }); } } ================================================ FILE: 1.x/Chapter3-2-10/src/test/resources/application.properties ================================================ spring.ldap.embedded.ldif=ldap-server.ldif spring.ldap.embedded.base-dn=dc=didispace,dc=com ================================================ FILE: 1.x/Chapter3-2-10/src/test/resources/ldap-server.ldif ================================================ dn: dc=didispace,dc=com objectClass: top objectClass: domain dn: ou=people,dc=didispace,dc=com objectclass: top objectclass: organizationalUnit ou: people dn: uid=ben,ou=people,dc=didispace,dc=com objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: didi sn: zhaiyongchao uid: didi userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ= ================================================ FILE: 1.x/Chapter3-2-11/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-11 1.0.0 jar Chapter3-2-11 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-mongodb com.spring4all mongodb-plus-spring-boot-starter 1.0.0.RELEASE org.projectlombok lombok 1.16.12 provided org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-11/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import com.spring4all.mongodb.EnableMongoPlus; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableMongoPlus @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-11/src/main/resources/application.properties ================================================ spring.data.mongodb.uri=mongodb://localhost:27017/test spring.data.mongodb.option.min-connection-per-host=20 spring.data.mongodb.option.max-connection-per-host=200 ================================================ FILE: 1.x/Chapter3-2-11/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.mongodb.MongoClient; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class ApplicationTests { @Autowired private MongoClient mongoClient; @Test public void test() throws Exception { log.info("MinConnectionsPerHost = {}, MaxConnectionsPerHost = {}", mongoClient.getMongoClientOptions().getMinConnectionsPerHost(), mongoClient.getMongoClientOptions().getConnectionsPerHost()); } } ================================================ FILE: 1.x/Chapter3-2-2/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-2 1.0.0 jar Chapter3-2-2 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-2/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-2/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/21 下午3:35. * @blog http://blog.didispace.com */ @Entity public class User { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; public User(){} public User(String name, Integer age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-2-2/src/main/java/com/didispace/domain/UserRepository.java ================================================ package com.didispace.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ public interface UserRepository extends JpaRepository { User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name); } ================================================ FILE: 1.x/Chapter3-2-2/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop ================================================ FILE: 1.x/Chapter3-2-2/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserRepository; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Test public void test() throws Exception { // 创建10条记录 userRepository.save(new User("AAA", 10)); userRepository.save(new User("BBB", 20)); userRepository.save(new User("CCC", 30)); userRepository.save(new User("DDD", 40)); userRepository.save(new User("EEE", 50)); userRepository.save(new User("FFF", 60)); userRepository.save(new User("GGG", 70)); userRepository.save(new User("HHH", 80)); userRepository.save(new User("III", 90)); userRepository.save(new User("JJJ", 100)); // 测试findAll, 查询所有记录 Assert.assertEquals(10, userRepository.findAll().size()); // 测试findByName, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue()); // 测试findUser, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue()); // 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName()); // 测试删除姓名为AAA的User userRepository.delete(userRepository.findByName("AAA")); // 测试findAll, 查询所有记录, 验证上面的删除是否成功 Assert.assertEquals(9, userRepository.findAll().size()); } } ================================================ FILE: 1.x/Chapter3-2-3/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-3 1.0.0 jar Chapter3-2-3 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-3/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-3/src/main/java/com/didispace/DataSourceConfig.java ================================================ package com.didispace; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/26 下午9:11. * @blog http://blog.didispace.com */ @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix="spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @Primary @ConfigurationProperties(prefix="spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "primaryJdbcTemplate") public JdbcTemplate primaryJdbcTemplate( @Qualifier("primaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean(name = "secondaryJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate( @Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } } ================================================ FILE: 1.x/Chapter3-2-3/src/main/resources/application.properties ================================================ spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=root spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=root spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver ================================================ FILE: 1.x/Chapter3-2-3/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired @Qualifier("primaryJdbcTemplate") protected JdbcTemplate jdbcTemplate1; @Autowired @Qualifier("secondaryJdbcTemplate") protected JdbcTemplate jdbcTemplate2; @Before public void setUp() { jdbcTemplate1.update("DELETE FROM USER "); jdbcTemplate2.update("DELETE FROM USER "); } @Test public void test() throws Exception { // 往第一个数据源中插入两条数据 jdbcTemplate1.update("insert into user(id,name,age) values(?, ?, ?)", 1, "aaa", 20); jdbcTemplate1.update("insert into user(id,name,age) values(?, ?, ?)", 2, "bbb", 30); // 往第二个数据源中插入一条数据,若插入的是第一个数据源,则会主键冲突报错 jdbcTemplate2.update("insert into user(id,name,age) values(?, ?, ?)", 1, "aaa", 20); // 查一下第一个数据源中是否有两条数据,验证插入是否成功 Assert.assertEquals("2", jdbcTemplate1.queryForObject("select count(1) from user", String.class)); // 查一下第一个数据源中是否有两条数据,验证插入是否成功 Assert.assertEquals("1", jdbcTemplate2.queryForObject("select count(1) from user", String.class)); } } ================================================ FILE: 1.x/Chapter3-2-4/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-4 1.0.0 jar Chapter3-2-4 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/DataSourceConfig.java ================================================ package com.didispace; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/26 下午9:11. * @blog http://blog.didispace.com */ @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix="spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @Primary @ConfigurationProperties(prefix="spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/PrimaryConfig.java ================================================ package com.didispace; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "com.didispace.domain.p" }) //设置Repository所在位置 public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Primary @Bean(name = "entityManagerFactoryPrimary") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) { return builder .dataSource(primaryDataSource) .properties(getVendorProperties(primaryDataSource)) .packages("com.didispace.domain.p") //设置实体类所在位置 .persistenceUnit("primaryPersistenceUnit") .build(); } @Autowired private JpaProperties jpaProperties; private Map getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/SecondaryConfig.java ================================================ package com.didispace; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "com.didispace.domain.s" }) //设置Repository所在位置 public class SecondaryConfig { @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) { return builder .dataSource(secondaryDataSource) .properties(getVendorProperties(secondaryDataSource)) .packages("com.didispace.domain.s") //设置实体类所在位置 .persistenceUnit("secondaryPersistenceUnit") .build(); } @Autowired private JpaProperties jpaProperties; private Map getVendorProperties(DataSource dataSource) { return jpaProperties.getHibernateProperties(dataSource); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/User.java ================================================ package com.didispace.domain.p; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/21 下午3:35. * @blog http://blog.didispace.com */ @Entity public class User { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; public User(){} public User(String name, Integer age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/UserRepository.java ================================================ package com.didispace.domain.p; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ public interface UserRepository extends JpaRepository { } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/Message.java ================================================ package com.didispace.domain.s; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/21 下午3:35. * @blog http://blog.didispace.com */ @Entity public class Message { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private String content; public Message(){} public Message(String name, String content) { this.name = name; this.content = content; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } ================================================ FILE: 1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/MessageRepository.java ================================================ package com.didispace.domain.s; import org.springframework.data.jpa.repository.JpaRepository; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ public interface MessageRepository extends JpaRepository { } ================================================ FILE: 1.x/Chapter3-2-4/src/main/resources/application.properties ================================================ spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=52261340 spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=52261340 spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop ================================================ FILE: 1.x/Chapter3-2-4/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.p.User; import com.didispace.domain.p.UserRepository; import com.didispace.domain.s.Message; import com.didispace.domain.s.MessageRepository; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private MessageRepository messageRepository; @Before public void setUp() { } @Test public void test() throws Exception { userRepository.save(new User("aaa", 10)); userRepository.save(new User("bbb", 20)); userRepository.save(new User("ccc", 30)); userRepository.save(new User("ddd", 40)); userRepository.save(new User("eee", 50)); Assert.assertEquals(5, userRepository.findAll().size()); messageRepository.save(new Message("o1", "aaaaaaaaaa")); messageRepository.save(new Message("o2", "bbbbbbbbbb")); messageRepository.save(new Message("o3", "cccccccccc")); Assert.assertEquals(3, messageRepository.findAll().size()); } } ================================================ FILE: 1.x/Chapter3-2-5/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-5 1.0.0 jar Chapter3-2-5 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-redis org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-5/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-5/src/main/java/com/didispace/RedisConfig.java ================================================ package com.didispace; import com.didispace.domain.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.*; /** * @author 程序猿DD * @version 1.0.0 * @date 16/4/15 下午3:19. * @blog http://blog.didispace.com */ @Configuration public class RedisConfig { @Bean JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory) { RedisTemplate template = new RedisTemplate(); template.setConnectionFactory(jedisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new RedisObjectSerializer()); return template; } } ================================================ FILE: 1.x/Chapter3-2-5/src/main/java/com/didispace/RedisObjectSerializer.java ================================================ package com.didispace; import org.springframework.core.convert.converter.Converter; import org.springframework.core.serializer.support.DeserializingConverter; import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; public class RedisObjectSerializer implements RedisSerializer { private Converter serializer = new SerializingConverter(); private Converter deserializer = new DeserializingConverter(); static final byte[] EMPTY_ARRAY = new byte[0]; public Object deserialize(byte[] bytes) { if (isEmpty(bytes)) { return null; } try { return deserializer.convert(bytes); } catch (Exception ex) { throw new SerializationException("Cannot deserialize", ex); } } public byte[] serialize(Object object) { if (object == null) { return EMPTY_ARRAY; } try { return serializer.convert(object); } catch (Exception ex) { return EMPTY_ARRAY; } } private boolean isEmpty(byte[] data) { return (data == null || data.length == 0); } } ================================================ FILE: 1.x/Chapter3-2-5/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; import java.io.Serializable; /** * @author 程序猿DD * @version 1.0.0 * @date 16/4/15 下午1:58. * @blog http://blog.didispace.com */ public class User implements Serializable { private static final long serialVersionUID = -1L; private String username; private Integer age; public User(String username, Integer age) { this.username = username; this.age = age; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-2-5/src/main/resources/application.properties ================================================ # REDIS (RedisProperties) # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=localhost # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=0 ================================================ FILE: 1.x/Chapter3-2-5/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate redisTemplate; @Test public void test() throws Exception { // 保存字符串 stringRedisTemplate.opsForValue().set("aaa", "111"); Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa")); // 保存对象 User user = new User("超人", 20); redisTemplate.opsForValue().set(user.getUsername(), user); user = new User("蝙蝠侠", 30); redisTemplate.opsForValue().set(user.getUsername(), user); user = new User("蜘蛛侠", 40); redisTemplate.opsForValue().set(user.getUsername(), user); Assert.assertEquals(20, redisTemplate.opsForValue().get("超人").getAge().longValue()); Assert.assertEquals(30, redisTemplate.opsForValue().get("蝙蝠侠").getAge().longValue()); Assert.assertEquals(40, redisTemplate.opsForValue().get("蜘蛛侠").getAge().longValue()); } } ================================================ FILE: 1.x/Chapter3-2-6/pom.xml ================================================ 4.0.0 com.didispace demo 1.0.0 jar demo Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-mongodb org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-6/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-6/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; import org.springframework.data.annotation.Id; /** * @author 程序猿DD * @version 1.0.0 * @date 16/4/27 下午10:04. * @blog http://blog.didispace.com */ public class User { @Id private Long id; private String username; private Integer age; public User(Long id, String username, Integer age) { this.id = id; this.username = username; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-2-6/src/main/java/com/didispace/domain/UserRepository.java ================================================ package com.didispace.domain; import org.springframework.data.mongodb.repository.MongoRepository; /** * @author 程序猿DD * @version 1.0.0 * @date 16/4/27 下午10:16. * @blog http://blog.didispace.com */ public interface UserRepository extends MongoRepository { User findByUsername(String username); } ================================================ FILE: 1.x/Chapter3-2-6/src/main/resources/application.properties ================================================ spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test ================================================ FILE: 1.x/Chapter3-2-6/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserRepository; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Before public void setUp() { userRepository.deleteAll(); } @Test public void test() throws Exception { // 创建三个User,并验证User总数 userRepository.save(new User(1L, "didi", 30)); userRepository.save(new User(2L, "mama", 40)); userRepository.save(new User(3L, "kaka", 50)); Assert.assertEquals(3, userRepository.findAll().size()); // 删除一个User,再验证User总数 User u = userRepository.findOne(1L); userRepository.delete(u); Assert.assertEquals(2, userRepository.findAll().size()); // 删除一个User,再验证User总数 u = userRepository.findByUsername("mama"); userRepository.delete(u); Assert.assertEquals(1, userRepository.findAll().size()); } } ================================================ FILE: 1.x/Chapter3-2-7/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-7 1.0.0 jar Chapter3-2-7 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter 1.1.1 mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-7/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-7/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; public class User { private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-2-7/src/main/java/com/didispace/domain/UserMapper.java ================================================ package com.didispace.domain; import org.apache.ibatis.annotations.*; @Mapper public interface UserMapper { @Select("SELECT * FROM USER WHERE NAME = #{name}") User findByName(@Param("name") String name); @Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})") int insert(@Param("name") String name, @Param("age") Integer age); } ================================================ FILE: 1.x/Chapter3-2-7/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ================================================ FILE: 1.x/Chapter3-2-7/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserMapper; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @Transactional public class ApplicationTests { @Autowired private UserMapper userMapper; @Test @Rollback public void findByName() throws Exception { userMapper.insert("AAA", 20); User u = userMapper.findByName("AAA"); Assert.assertEquals(20, u.getAge().intValue()); } } ================================================ FILE: 1.x/Chapter3-2-8/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-8 1.0.0 jar Chapter3-2-8 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter 1.1.1 mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-8/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-8/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; public class User { private Long id; private String name; private Integer age; public User() { } public User(Long id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } public User(String name, Integer age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-2-8/src/main/java/com/didispace/domain/UserMapper.java ================================================ package com.didispace.domain; import org.apache.ibatis.annotations.*; import java.util.List; import java.util.Map; @Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE name = #{name}") User findByName(@Param("name") String name); @Results({ @Result(property = "name", column = "name"), @Result(property = "age", column = "age") }) @Select("SELECT name, age FROM user") List findAll(); @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})") int insert(@Param("name") String name, @Param("age") Integer age); @Update("UPDATE user SET age=#{age} WHERE name=#{name}") void update(User user); @Delete("DELETE FROM user WHERE id =#{id}") void delete(Long id); @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})") int insertByUser(User user); @Insert("INSERT INTO user(name, age) VALUES(#{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER})") int insertByMap(Map map); } ================================================ FILE: 1.x/Chapter3-2-8/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ================================================ FILE: 1.x/Chapter3-2-8/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserMapper; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; import java.util.List; import java.util.Map; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @Transactional public class ApplicationTests { @Autowired private UserMapper userMapper; @Test @Rollback public void testUserMapper() throws Exception { // insert一条数据,并select出来验证 userMapper.insert("AAA", 20); User u = userMapper.findByName("AAA"); Assert.assertEquals(20, u.getAge().intValue()); // update一条数据,并select出来验证 u.setAge(30); userMapper.update(u); u = userMapper.findByName("AAA"); Assert.assertEquals(30, u.getAge().intValue()); // 删除这条数据,并select验证 userMapper.delete(u.getId()); u = userMapper.findByName("AAA"); Assert.assertEquals(null, u); u = new User("BBB", 30); userMapper.insertByUser(u); Assert.assertEquals(30, userMapper.findByName("BBB").getAge().intValue()); Map map = new HashMap<>(); map.put("name", "CCC"); map.put("age", 40); userMapper.insertByMap(map); Assert.assertEquals(40, userMapper.findByName("CCC").getAge().intValue()); List userList = userMapper.findAll(); for(User user : userList) { Assert.assertEquals(null, user.getId()); Assert.assertNotEquals(null, user.getName()); } } } ================================================ FILE: 1.x/Chapter3-2-9/pom.xml ================================================ 4.0.0 com.didispace Chapter3-2-9 1.0.0 jar Chapter3-2-9 Spring Boot with JDBCTemplate org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-jdbc org.flywaydb flyway-core 5.0.3 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-2-9/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserService.java ================================================ package com.didispace.service; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/17 下午7:04. * @blog http://blog.didispace.com */ public interface UserService { /** * 新增一个用户 * @param name * @param age */ void create(String name, Integer age); /** * 根据name删除一个用户高 * @param name */ void deleteByName(String name); /** * 获取用户总量 */ Integer getAllUsers(); /** * 删除所有用户 */ void deleteAllUsers(); } ================================================ FILE: 1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserServiceImpl.java ================================================ package com.didispace.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/17 下午6:44. * @blog http://blog.didispace.com */ @Service public class UserServiceImpl implements UserService { @Autowired private JdbcTemplate jdbcTemplate; @Override public void create(String name, Integer age) { jdbcTemplate.update("insert into user(NAME, AGE) values(?, ?)", name, age); } @Override public void deleteByName(String name) { jdbcTemplate.update("delete from user where NAME = ?", name); } @Override public Integer getAllUsers() { return jdbcTemplate.queryForObject("select count(1) from user", Integer.class); } @Override public void deleteAllUsers() { jdbcTemplate.update("delete from user"); } } ================================================ FILE: 1.x/Chapter3-2-9/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.jdbc.Driver flyway.locations=classpath:/db ================================================ FILE: 1.x/Chapter3-2-9/src/main/resources/db/V1__Base_version.sql ================================================ DROP TABLE IF EXISTS `user` ; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(30) NOT NULL COMMENT '姓名', `age` int(5) DEFAULT NULL COMMENT '年龄', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ================================================ FILE: 1.x/Chapter3-2-9/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.service.UserService; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class ApplicationTests { @Autowired private UserService userSerivce; @Before public void setUp() { // 准备,清空user表 userSerivce.deleteAllUsers(); } @Test public void test() throws Exception { // 插入5个用户 userSerivce.create("a", 1); userSerivce.create("b", 2); userSerivce.create("c", 3); userSerivce.create("d", 4); userSerivce.create("e", 5); // 查数据库,应该有5个用户 Assert.assertEquals(5, userSerivce.getAllUsers().intValue()); // 删除两个用户 userSerivce.deleteByName("a"); userSerivce.deleteByName("e"); // 查数据库,应该有5个用户 Assert.assertEquals(3, userSerivce.getAllUsers().intValue()); } } ================================================ FILE: 1.x/Chapter3-3-1/pom.xml ================================================ 4.0.0 com.didispace Chapter3-3-1 1.0.0 jar Chapter3-3-1 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter3-3-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter3-3-1/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/21 下午3:35. * @blog http://blog.didispace.com */ @Entity public class User { @Id @GeneratedValue private Long id; @Column(nullable = false, length = 5) private String name; @Column(nullable = false) private Integer age; public User(){} public User(String name, Integer age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter3-3-1/src/main/java/com/didispace/domain/UserRepository.java ================================================ package com.didispace.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ public interface UserRepository extends JpaRepository { User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name); } ================================================ FILE: 1.x/Chapter3-3-1/src/main/java/com/didispace/service/UserService.java ================================================ package com.didispace.service; import com.didispace.domain.User; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * Created by Administrator on 2016/5/27. */ public interface UserService { @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED) User login(String name, String password); } ================================================ FILE: 1.x/Chapter3-3-1/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=create ================================================ FILE: 1.x/Chapter3-3-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserRepository; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Test @Transactional public void test() throws Exception { // 创建10条记录 userRepository.save(new User("AAA", 10)); userRepository.save(new User("BBB", 20)); userRepository.save(new User("CCC", 30)); userRepository.save(new User("DDD", 40)); userRepository.save(new User("EEE", 50)); userRepository.save(new User("FFF", 60)); userRepository.save(new User("GGG", 70)); userRepository.save(new User("HHHHHHHHH", 80)); userRepository.save(new User("III", 90)); userRepository.save(new User("JJJ", 100)); // 测试findAll, 查询所有记录 Assert.assertEquals(10, userRepository.findAll().size()); // 测试findByName, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue()); // 测试findUser, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue()); // 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName()); // 测试删除姓名为AAA的User userRepository.delete(userRepository.findByName("AAA")); // 测试findAll, 查询所有记录, 验证上面的删除是否成功 Assert.assertEquals(9, userRepository.findAll().size()); } } ================================================ FILE: 1.x/Chapter4-1-1/pom.xml ================================================ 4.0.0 com.didispace Chapter4-1-1 1.0.0 jar Chapter4-1-1 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-1-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-1-1/src/main/java/com/didispace/task/ScheduledTasks.java ================================================ package com.didispace.task; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @Component public class ScheduledTasks { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(fixedRate = 5000) public void reportCurrentTime() { System.out.println("当前时间:" + dateFormat.format(new Date())); } } ================================================ FILE: 1.x/Chapter4-1-1/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-1-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Test public void getHello() throws Exception { } } ================================================ FILE: 1.x/Chapter4-1-2/pom.xml ================================================ 4.0.0 com.didispace Chapter4-1-2 1.0.0 jar Chapter4-1-2 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-1-2/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableAsync public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-1-2/src/main/java/com/didispace/async/Task.java ================================================ package com.didispace.async; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.stereotype.Component; import java.util.Random; import java.util.concurrent.Future; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/16 下午12:58. * @blog http://blog.didispace.com */ @Component public class Task { public static Random random =new Random(); @Async public Future doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); return new AsyncResult<>("任务一完成"); } @Async public Future doTaskTwo() throws Exception { System.out.println("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务二,耗时:" + (end - start) + "毫秒"); return new AsyncResult<>("任务二完成"); } @Async public Future doTaskThree() throws Exception { System.out.println("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务三,耗时:" + (end - start) + "毫秒"); return new AsyncResult<>("任务三完成"); } } ================================================ FILE: 1.x/Chapter4-1-2/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-1-2/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.async.Task; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.concurrent.Future; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Autowired private Task task; @Test public void test() throws Exception { long start = System.currentTimeMillis(); Future task1 = task.doTaskOne(); Future task2 = task.doTaskTwo(); Future task3 = task.doTaskThree(); while(true) { if(task1.isDone() && task2.isDone() && task3.isDone()) { // 三个任务都调用完成,退出循环等待 break; } Thread.sleep(1000); } long end = System.currentTimeMillis(); System.out.println("任务全部完成,总耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 1.x/Chapter4-1-3/pom.xml ================================================ 4.0.0 com.didispace Chapter4-1-3 1.0.0 jar Chapter4-1-3 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.projectlombok lombok 1.16.20 provided org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-1-3/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @EnableAsync @Configuration class TaskPoolConfig { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(200); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("taskExecutor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } } } ================================================ FILE: 1.x/Chapter4-1-3/src/main/java/com/didispace/async/Task.java ================================================ package com.didispace.async; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.Random; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/16 下午12:58. * @blog http://blog.didispace.com */ @Slf4j @Component public class Task { public static Random random = new Random(); @Async("taskExecutor") public void doTaskOne() throws Exception { log.info("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务一,耗时:" + (end - start) + "毫秒"); } @Async("taskExecutor") public void doTaskTwo() throws Exception { log.info("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务二,耗时:" + (end - start) + "毫秒"); } @Async("taskExecutor") public void doTaskThree() throws Exception { log.info("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务三,耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 1.x/Chapter4-1-3/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-1-3/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.async.Task; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class ApplicationTests { @Autowired private Task task; @Test public void test() throws Exception { task.doTaskOne(); task.doTaskTwo(); task.doTaskThree(); Thread.currentThread().join(); } } ================================================ FILE: 1.x/Chapter4-1-4/pom.xml ================================================ 4.0.0 com.didispace Chapter4-1-4 1.0.0 jar Chapter4-1-4 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-redis org.projectlombok lombok 1.16.20 provided org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-1-4/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import java.util.concurrent.Executor; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @EnableAsync @Configuration class TaskPoolConfig { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler(); executor.setPoolSize(20); executor.setThreadNamePrefix("taskExecutor-"); executor.setWaitForTasksToCompleteOnShutdown(true); executor.setAwaitTerminationSeconds(60); return executor; } } } ================================================ FILE: 1.x/Chapter4-1-4/src/main/java/com/didispace/async/Task.java ================================================ package com.didispace.async; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/16 下午12:58. * @blog http://blog.didispace.com */ @Slf4j @Component public class Task { @Autowired private StringRedisTemplate stringRedisTemplate; @Async("taskExecutor") public void doTaskOne() throws Exception { log.info("开始做任务一"); long start = System.currentTimeMillis(); log.info(stringRedisTemplate.randomKey()); long end = System.currentTimeMillis(); log.info("完成任务一,耗时:" + (end - start) + "毫秒"); } @Async("taskExecutor") public void doTaskTwo() throws Exception { log.info("开始做任务二"); long start = System.currentTimeMillis(); log.info(stringRedisTemplate.randomKey()); long end = System.currentTimeMillis(); log.info("完成任务二,耗时:" + (end - start) + "毫秒"); } @Async("taskExecutor") public void doTaskThree() throws Exception { log.info("开始做任务三"); long start = System.currentTimeMillis(); log.info(stringRedisTemplate.randomKey()); long end = System.currentTimeMillis(); log.info("完成任务三,耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 1.x/Chapter4-1-4/src/main/resources/application.properties ================================================ spring.redis.pool.max-wait=5000 spring.redis.pool.max-active=10 ================================================ FILE: 1.x/Chapter4-1-4/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.async.Task; import lombok.SneakyThrows; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class ApplicationTests { @Autowired private Task task; @Test @SneakyThrows public void test() { for (int i = 0; i < 10000; i++) { task.doTaskOne(); task.doTaskTwo(); task.doTaskThree(); if (i == 9999) { System.exit(0); } } } } ================================================ FILE: 1.x/Chapter4-1-5/pom.xml ================================================ 4.0.0 com.didispace Chapter4-1-5 1.0.0 jar Chapter4-1-5 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.projectlombok lombok 1.16.20 provided org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-1-5/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @EnableAsync @Configuration class TaskPoolConfig { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(200); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("taskExecutor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } } } ================================================ FILE: 1.x/Chapter4-1-5/src/main/java/com/didispace/async/Task.java ================================================ package com.didispace.async; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.stereotype.Component; import java.util.Random; import java.util.concurrent.Future; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/16 下午12:58. * @blog http://blog.didispace.com */ @Slf4j @Component public class Task { public static Random random = new Random(); @Async("taskExecutor") public Future run() throws Exception { long sleep = random.nextInt(10000); log.info("开始任务,需耗时:" + sleep + "毫秒"); Thread.sleep(sleep); log.info("完成任务"); return new AsyncResult<>("test"); } } ================================================ FILE: 1.x/Chapter4-1-5/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-1-5/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.async.Task; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @Slf4j @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class ApplicationTests { @Autowired private Task task; @Test public void test() throws Exception { Future futureResult = task.run(); String result = futureResult.get(5, TimeUnit.SECONDS); log.info(result); } } ================================================ FILE: 1.x/Chapter4-2-2/pom.xml ================================================ 4.0.0 com.didispace Chapter4-2-2 1.0.0 jar Chapter4-2-2 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-log4j org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-2-2/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-2-2/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-2-2/src/main/resources/log4j.properties ================================================ # LOG4J配置 log4j.rootCategory=INFO, stdout, file, errorfile log4j.category.com.didispace=DEBUG, didifile log4j.logger.error=errorfile # 控制台输出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # root日志输出 log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.file=logs/all.log log4j.appender.file.DatePattern='.'yyyy-MM-dd log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # error日志输出 log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.errorfile.file=logs/error.log log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd log4j.appender.errorfile.Threshold = ERROR log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # com.didispace下的日志输出 log4j.appender.didifile=org.apache.log4j.DailyRollingFileAppender log4j.appender.didifile.file=logs/my.log log4j.appender.didifile.DatePattern='.'yyyy-MM-dd log4j.appender.didifile.layout=org.apache.log4j.PatternLayout log4j.appender.didifile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n ================================================ FILE: 1.x/Chapter4-2-2/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { private Logger logger = Logger.getLogger(getClass()); @Test public void test() throws Exception { logger.info("输出info"); logger.debug("输出debug"); logger.error("输出error"); } } ================================================ FILE: 1.x/Chapter4-2-3/pom.xml ================================================ 4.0.0 com.didispace Chapter4-2-3 1.0.0 jar Chapter4-2-3 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-log4j org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-2-3/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-2-3/src/main/resources/application-dev.properties ================================================ logging.level.com.didispace=INFO ================================================ FILE: 1.x/Chapter4-2-3/src/main/resources/application-prod.properties ================================================ logging.level.com.didispace=INFO ================================================ FILE: 1.x/Chapter4-2-3/src/main/resources/application-test.properties ================================================ logging.level.com.didispace=DEBUG ================================================ FILE: 1.x/Chapter4-2-3/src/main/resources/application.properties ================================================ spring.profiles.active=dev ================================================ FILE: 1.x/Chapter4-2-3/src/main/resources/log4j.properties ================================================ # LOG4J配置 log4j.rootCategory=INFO, stdout, file, errorfile log4j.category.com.didispace=${logging.level.com.didispace}, didifile log4j.logger.error=errorfile # 控制台输出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # root日志输出 log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.file=logs/all.log log4j.appender.file.DatePattern='.'yyyy-MM-dd log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # error日志输出 log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.errorfile.file=logs/error.log log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd log4j.appender.errorfile.Threshold = ERROR log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # com.didispace下的日志输出 log4j.appender.didifile=org.apache.log4j.DailyRollingFileAppender log4j.appender.didifile.file=logs/my.log log4j.appender.didifile.DatePattern='.'yyyy-MM-dd log4j.appender.didifile.layout=org.apache.log4j.PatternLayout log4j.appender.didifile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n ================================================ FILE: 1.x/Chapter4-2-3/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { private Logger logger = Logger.getLogger(getClass()); @Test public void test() throws Exception { logger.info("输出info"); logger.debug("输出debug"); logger.error("输出error"); } } ================================================ FILE: 1.x/Chapter4-2-4/pom.xml ================================================ 4.0.0 com.didispace Chapter4-2-4 1.0.0 jar Chapter4-2-4 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-log4j org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-2-4/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-2-4/src/main/java/com/didispace/aspect/WebLogAspect.java ================================================ package com.didispace.aspect; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; /** * Web层日志切面 * * @author 程序猿DD * @version 1.0.0 * @date 16/5/17 上午10:42. * @blog http://blog.didispace.com */ @Aspect @Order(5) @Component public class WebLogAspect { private Logger logger = Logger.getLogger(getClass()); ThreadLocal startTime = new ThreadLocal<>(); @Pointcut("execution(public * com.didispace.web..*.*(..))") public void webLog(){} @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { startTime.set(System.currentTimeMillis()); // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 记录下请求内容 logger.info("URL : " + request.getRequestURL().toString()); logger.info("HTTP_METHOD : " + request.getMethod()); logger.info("IP : " + request.getRemoteAddr()); logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs())); } @AfterReturning(returning = "ret", pointcut = "webLog()") public void doAfterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 logger.info("RESPONSE : " + ret); logger.info("SPEND TIME : " + (System.currentTimeMillis() - startTime.get())); } } ================================================ FILE: 1.x/Chapter4-2-4/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.*; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/19 下午1:27. * @blog http://blog.didispace.com */ @RestController public class HelloController { @RequestMapping(value = "/hello", method = RequestMethod.GET) @ResponseBody public String hello(@RequestParam String name) { return "Hello " + name; } } ================================================ FILE: 1.x/Chapter4-2-4/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-2-4/src/main/resources/log4j.properties ================================================ # LOG4J配置 log4j.rootCategory=INFO, stdout, file, errorfile log4j.category.com.didispace=DEBUG, didifile log4j.logger.error=errorfile # 控制台输出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # root日志输出 log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.file=logs/all.log log4j.appender.file.DatePattern='.'yyyy-MM-dd log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # error日志输出 log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.errorfile.file=logs/error.log log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd log4j.appender.errorfile.Threshold = ERROR log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # com.didispace下的日志输出 log4j.appender.didifile=org.apache.log4j.DailyRollingFileAppender log4j.appender.didifile.file=logs/my.log log4j.appender.didifile.DatePattern='.'yyyy-MM-dd log4j.appender.didifile.layout=org.apache.log4j.PatternLayout log4j.appender.didifile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n ================================================ FILE: 1.x/Chapter4-2-4/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { private Logger logger = Logger.getLogger(getClass()); @Test public void test() throws Exception { logger.info("输出info"); logger.debug("输出debug"); logger.error("输出error"); } } ================================================ FILE: 1.x/Chapter4-2-5/pom.xml ================================================ 4.0.0 com.didispace Chapter4-2-5 1.0.0 jar Chapter4-2-5 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-log4j org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-test test org.mongodb mongodb-driver 3.2.2 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-2-5/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-2-5/src/main/java/com/didispace/aspect/WebLogAspect.java ================================================ package com.didispace.aspect; import com.mongodb.BasicDBObject; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * Web层日志切面 * * @author 程序猿DD * @version 1.0.0 * @date 16/5/17 上午10:42. * @blog http://blog.didispace.com */ @Aspect @Order(1) @Component public class WebLogAspect { private Logger logger = Logger.getLogger("mongodb"); @Pointcut("execution(public * com.didispace.web..*.*(..))") public void webLog(){} @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 获取HttpServletRequest ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 获取要记录的日志内容 BasicDBObject logInfo = getBasicDBObject(request, joinPoint); logger.info(logInfo); } private BasicDBObject getBasicDBObject(HttpServletRequest request, JoinPoint joinPoint) { // 基本信息 BasicDBObject r = new BasicDBObject(); r.append("requestURL", request.getRequestURL().toString()); r.append("requestURI", request.getRequestURI()); r.append("queryString", request.getQueryString()); r.append("remoteAddr", request.getRemoteAddr()); r.append("remoteHost", request.getRemoteHost()); r.append("remotePort", request.getRemotePort()); r.append("localAddr", request.getLocalAddr()); r.append("localName", request.getLocalName()); r.append("method", request.getMethod()); r.append("headers", getHeadersInfo(request)); r.append("parameters", request.getParameterMap()); r.append("classMethod", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); r.append("args", Arrays.toString(joinPoint.getArgs())); return r; } /** * 获取头信息 * * @param request * @return */ private Map getHeadersInfo(HttpServletRequest request) { Map map = new HashMap<>(); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String key = (String) headerNames.nextElement(); String value = request.getHeader(key); map.put(key, value); } return map; } } ================================================ FILE: 1.x/Chapter4-2-5/src/main/java/com/didispace/log/MongoAppender.java ================================================ package com.didispace.log; import com.mongodb.BasicDBObject; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.spi.LoggingEvent; /** * 日志插入MongoDB * * @author 程序猿DD * @version 1.0.0 * @date 16/5/23 下午4:53. * @blog http://blog.didispace.com */ public class MongoAppender extends AppenderSkeleton { private MongoClient mongoClient; private MongoDatabase mongoDatabase; private MongoCollection logsCollection; private String connectionUrl; private String databaseName; private String collectionName; @Override protected void append(LoggingEvent loggingEvent) { if(mongoDatabase == null) { MongoClientURI connectionString = new MongoClientURI(connectionUrl); mongoClient = new MongoClient(connectionString); mongoDatabase = mongoClient.getDatabase(databaseName); logsCollection = mongoDatabase.getCollection(collectionName, BasicDBObject.class); } logsCollection.insertOne((BasicDBObject) loggingEvent.getMessage()); } @Override public void close() { if(mongoClient != null) { mongoClient.close(); } } @Override public boolean requiresLayout() { return false; } public String getConnectionUrl() { return connectionUrl; } public void setConnectionUrl(String connectionUrl) { this.connectionUrl = connectionUrl; } public String getDatabaseName() { return databaseName; } public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } public String getCollectionName() { return collectionName; } public void setCollectionName(String collectionName) { this.collectionName = collectionName; } } ================================================ FILE: 1.x/Chapter4-2-5/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.*; /** * @author 程序猿DD * @version 1.0.0 * @date 16/5/19 下午1:27. * @blog http://blog.didispace.com */ @RestController public class HelloController { @RequestMapping(value = "/hello", method = RequestMethod.GET) @ResponseBody public String hello(@RequestParam String name) { return "Hello " + name; } } ================================================ FILE: 1.x/Chapter4-2-5/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-2-5/src/main/resources/log4j.properties ================================================ # LOG4J配置 log4j.rootCategory=INFO, stdout log4j.logger.mongodb=INFO, mongodb # 控制台输出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n # mongodb输出 log4j.appender.mongodb=com.didispace.log.MongoAppender log4j.appender.mongodb.connectionUrl=mongodb://localhost:27017 log4j.appender.mongodb.databaseName=logs log4j.appender.mongodb.collectionName=logs_request ================================================ FILE: 1.x/Chapter4-2-5/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Before public void setUp() throws Exception { } @Test public void getHello() throws Exception { } } ================================================ FILE: 1.x/Chapter4-2-6/pom.xml ================================================ 4.0.0 com.didispace demo 0.0.1-SNAPSHOT jar demo Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-2-6/src/main/java/com/didispace/DemoApplication.java ================================================ package com.didispace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication public class DemoApplication { private Logger logger = LoggerFactory.getLogger(getClass()); @RequestMapping(value = "/test", method = RequestMethod.GET) public String testLogLevel() { logger.debug("Logger Level :DEBUG"); logger.info("Logger Level :INFO"); logger.error("Logger Level :ERROR"); return ""; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ================================================ FILE: 1.x/Chapter4-2-6/src/main/resources/application.properties ================================================ management.security.enabled=false ================================================ FILE: 1.x/Chapter4-2-6/src/test/java/com/didispace/DemoApplicationTests.java ================================================ package com.didispace; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class DemoApplicationTests { @Test public void contextLoads() { } } ================================================ FILE: 1.x/Chapter4-3-1/pom.xml ================================================ 4.0.0 com.didispace Chapter4-3-1 1.0.0 jar Chapter4-3-1 Spring Boot with Thymeleaf org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 1.x/Chapter4-3-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-3-1/src/main/java/com/didispace/WebSecurityConfig.java ================================================ package com.didispace; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } } ================================================ FILE: 1.x/Chapter4-3-1/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class HelloController { @RequestMapping("/") public String index() { return "index"; } @RequestMapping("/hello") public String hello() { return "hello"; } @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } } ================================================ FILE: 1.x/Chapter4-3-1/src/main/resources/application.properties ================================================ ================================================ FILE: 1.x/Chapter4-3-1/src/main/resources/templates/hello.html ================================================ Hello World!

Hello [[${#httpServletRequest.remoteUser}]]!

================================================ FILE: 1.x/Chapter4-3-1/src/main/resources/templates/index.html ================================================ Spring Security入门

欢迎使用Spring Security!

点击 这里 打个招呼吧

================================================ FILE: 1.x/Chapter4-3-1/src/main/resources/templates/login.html ================================================ Spring Security Example
用户名或密码错
您已注销成功
================================================ FILE: 1.x/Chapter4-3-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.HelloController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup( new HelloController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter4-4-1/pom.xml ================================================ 4.0.0 com.didispace Chapter4-4-1 1.0.0 jar Chapter4-4-1 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-cache net.sf.ehcache ehcache org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-4-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ @SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-4-1/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/21 下午3:35. * @blog http://blog.didispace.com */ @Entity public class User { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; public User(){} public User(String name, Integer age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter4-4-1/src/main/java/com/didispace/domain/UserRepository.java ================================================ package com.didispace.domain; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ @CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository { @Cacheable(key = "#p0", condition = "#p0.length() < 10") User findByName(String name); } ================================================ FILE: 1.x/Chapter4-4-1/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.jpa.properties.hibernate.show_sql=true ================================================ FILE: 1.x/Chapter4-4-1/src/main/resources/ehcache.xml ================================================ ================================================ FILE: 1.x/Chapter4-4-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserRepository; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.cache.CacheManager; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private CacheManager cacheManager; @Before public void before() { userRepository.save(new User("AAA", 10)); } @Test public void test() throws Exception { User u1 = userRepository.findByName("AAA"); System.out.println("第一次查询:" + u1.getAge()); User u2 = userRepository.findByName("AAA"); System.out.println("第二次查询:" + u2.getAge()); u1.setAge(20); userRepository.save(u1); User u3 = userRepository.findByName("AAA"); System.out.println("第三次查询:" + u3.getAge()); } } ================================================ FILE: 1.x/Chapter4-4-2/pom.xml ================================================ 4.0.0 com.didispace Chapter4-4-2 1.0.0 jar Chapter4-4-2 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java 5.1.21 org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-cache org.springframework.boot spring-boot-starter-redis org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-4-2/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ @SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-4-2/src/main/java/com/didispace/domain/User.java ================================================ package com.didispace.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.io.Serializable; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/21 下午3:35. * @blog http://blog.didispace.com */ @Entity public class User implements Serializable { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer age; public User(){} public User(String name, Integer age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } ================================================ FILE: 1.x/Chapter4-4-2/src/main/java/com/didispace/domain/UserRepository.java ================================================ package com.didispace.domain; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ @CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository { @Cacheable(key = "#p0") User findByName(String name); @CachePut(key = "#p0.name") User save(User user); } ================================================ FILE: 1.x/Chapter4-4-2/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.jpa.properties.hibernate.show_sql=true spring.redis.host=localhost spring.redis.port=6379 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.pool.max-active=8 spring.redis.pool.max-wait=-1 ================================================ FILE: 1.x/Chapter4-4-2/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.domain.User; import com.didispace.domain.UserRepository; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.cache.CacheManager; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author 程序猿DD * @version 1.0.0 * @date 16/3/23 下午2:34. * @blog http://blog.didispace.com */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private CacheManager cacheManager; @Before public void before() { userRepository.save(new User("AAA", 10)); } @Test public void test() throws Exception { User u1 = userRepository.findByName("AAA"); System.out.println("第一次查询:" + u1.getAge()); User u2 = userRepository.findByName("AAA"); System.out.println("第二次查询:" + u2.getAge()); u1.setAge(20); userRepository.save(u1); User u3 = userRepository.findByName("AAA"); System.out.println("第三次查询:" + u3.getAge()); } } ================================================ FILE: 1.x/Chapter4-5-1/pom.xml ================================================ 4.0.0 com.didispace Chapter4-5-1 1.0.0 jar Chapter4-5-1 Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-mail org.springframework.boot spring-boot-starter-velocity org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter4-5-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter4-5-1/src/main/resources/application.properties ================================================ spring.mail.host=smtp.qq.com spring.mail.username=username@qq.com spring.mail.password=password spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true ================================================ FILE: 1.x/Chapter4-5-1/src/main/resources/templates/template.vm ================================================

你好, ${username}, 这是一封模板邮件!

================================================ FILE: 1.x/Chapter4-5-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.apache.commons.collections.map.HashedMap; import org.apache.velocity.app.VelocityEngine; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.ui.velocity.VelocityEngineUtils; import javax.mail.internet.MimeMessage; import java.io.File; import java.util.Map; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Autowired private JavaMailSender mailSender; @Autowired private VelocityEngine velocityEngine; @Test public void sendSimpleMail() throws Exception { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("dyc87112@qq.com"); message.setTo("dyc87112@qq.com"); message.setSubject("主题:简单邮件"); message.setText("测试邮件内容"); mailSender.send(message); } @Test public void sendAttachmentsMail() throws Exception { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom("dyc87112@qq.com"); helper.setTo("dyc87112@qq.com"); helper.setSubject("主题:有附件"); helper.setText("有附件的邮件"); FileSystemResource file = new FileSystemResource(new File("weixin.jpg")); helper.addAttachment("附件-1.jpg", file); helper.addAttachment("附件-2.jpg", file); mailSender.send(mimeMessage); } @Test public void sendInlineMail() throws Exception { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom("dyc87112@qq.com"); helper.setTo("dyc87112@qq.com"); helper.setSubject("主题:嵌入静态资源"); helper.setText("", true); FileSystemResource file = new FileSystemResource(new File("weixin.jpg")); helper.addInline("weixin", file); mailSender.send(mimeMessage); } @Test public void sendTemplateMail() throws Exception { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom("dyc87112@qq.com"); helper.setTo("dyc87112@qq.com"); helper.setSubject("主题:模板邮件"); Map model = new HashedMap(); model.put("username", "didi"); String text = VelocityEngineUtils.mergeTemplateIntoString( velocityEngine, "template.vm", "UTF-8", model); helper.setText(text, true); mailSender.send(mimeMessage); } } ================================================ FILE: 1.x/Chapter5-2-1/pom.xml ================================================ 4.0.0 com.didispace rabbitmq-hello 0.0.1-SNAPSHOT jar rabbitmq-hello Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.3.7.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-amqp org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter5-2-1/src/main/java/com/didispace/HelloApplication.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class, args); } } ================================================ FILE: 1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/RabbitConfig.java ================================================ package com.didispace.rabbit; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author 翟永超 * @create 2016/9/25. * @blog http://blog.didispace.com */ @Configuration public class RabbitConfig { @Bean public Queue helloQueue() { return new Queue("hello"); } } ================================================ FILE: 1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Receiver.java ================================================ package com.didispace.rabbit; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; import java.util.Date; /** * @author 翟永超 * @create 2016/9/25. * @blog http://blog.didispace.com */ @Component @RabbitListener(queues = "hello") public class Receiver { @RabbitHandler public void process(String hello) { System.out.println("Receiver : " + hello); } } ================================================ FILE: 1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Sender.java ================================================ package com.didispace.rabbit; import org.springframework.amqp.core.AmqpTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; @Component public class Sender { @Autowired private AmqpTemplate rabbitTemplate; public void send() { String context = "hello " + new Date(); System.out.println("Sender : " + context); this.rabbitTemplate.convertAndSend("hello", context); } } ================================================ FILE: 1.x/Chapter5-2-1/src/main/resources/application.properties ================================================ spring.application.name=rabbitmq-hello spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=springcloud spring.rabbitmq.password=123456 ================================================ FILE: 1.x/Chapter5-2-1/src/test/java/com/didispace/HelloApplicationTests.java ================================================ package com.didispace; import com.didispace.rabbit.Sender; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = HelloApplication.class) public class HelloApplicationTests { @Autowired private Sender sender; @Test public void hello() throws Exception { sender.send(); } } ================================================ FILE: 1.x/Chapter6-1-1/pom.xml ================================================ 4.0.0 com.didispace statemachine 0.0.1-SNAPSHOT jar statemachine Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 1.4.2.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.statemachine spring-statemachine-core 1.2.0.RELEASE org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter6-1-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.statemachine.StateMachine; @SpringBootApplication public class Application implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Autowired private StateMachine stateMachine; @Override public void run(String... args) throws Exception { stateMachine.start(); stateMachine.sendEvent(Events.PAY); stateMachine.sendEvent(Events.RECEIVE); } } ================================================ FILE: 1.x/Chapter6-1-1/src/main/java/com/didispace/EventConfig.java ================================================ package com.didispace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.statemachine.annotation.*; /** * 该配置实现了com.didispace.StateMachineConfig类中定义的状态机监听器实现。 */ @WithStateMachine public class EventConfig { private Logger logger = LoggerFactory.getLogger(getClass()); @OnTransition(target = "UNPAID") public void create() { logger.info("订单创建,待支付"); } @OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE") public void pay() { logger.info("用户完成支付,待收货"); } @OnTransitionStart(source = "UNPAID", target = "WAITING_FOR_RECEIVE") public void payStart() { logger.info("用户完成支付,待收货: start"); } @OnTransitionEnd(source = "UNPAID", target = "WAITING_FOR_RECEIVE") public void payEnd() { logger.info("用户完成支付,待收货: end"); } @OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE") public void receive() { logger.info("用户已收货,订单完成"); } } ================================================ FILE: 1.x/Chapter6-1-1/src/main/java/com/didispace/Events.java ================================================ package com.didispace; public enum Events { PAY, // 支付 RECEIVE // 收货 } ================================================ FILE: 1.x/Chapter6-1-1/src/main/java/com/didispace/StateMachineConfig.java ================================================ package com.didispace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; import org.springframework.statemachine.listener.StateMachineListener; import org.springframework.statemachine.listener.StateMachineListenerAdapter; import org.springframework.statemachine.transition.Transition; import java.util.EnumSet; @Configuration @EnableStateMachine public class StateMachineConfig extends EnumStateMachineConfigurerAdapter { private Logger logger = LoggerFactory.getLogger(getClass()); @Override public void configure(StateMachineStateConfigurer states) throws Exception { states .withStates() .initial(States.UNPAID) .states(EnumSet.allOf(States.class)); } @Override public void configure(StateMachineTransitionConfigurer transitions) throws Exception { transitions .withExternal() .source(States.UNPAID).target(States.WAITING_FOR_RECEIVE) .event(Events.PAY) .and() .withExternal() .source(States.WAITING_FOR_RECEIVE).target(States.DONE) .event(Events.RECEIVE); } // @Override // public void configure(StateMachineConfigurationConfigurer config) // throws Exception { // config // .withConfiguration() // .listener(listener()); // } // // @Bean // public StateMachineListener listener() { // return new StateMachineListenerAdapter() { // // @Override // public void transition(Transition transition) { // if(transition.getTarget().getId() == States.UNPAID) { // logger.info("订单创建,待支付"); // return; // } // // if(transition.getSource().getId() == States.UNPAID // && transition.getTarget().getId() == States.WAITING_FOR_RECEIVE) { // logger.info("用户完成支付,待收货"); // return; // } // // if(transition.getSource().getId() == States.WAITING_FOR_RECEIVE // && transition.getTarget().getId() == States.DONE) { // logger.info("用户已收货,订单完成"); // return; // } // } // // }; // } } ================================================ FILE: 1.x/Chapter6-1-1/src/main/java/com/didispace/States.java ================================================ package com.didispace; public enum States { UNPAID, // 待支付 WAITING_FOR_RECEIVE, // 待收货 DONE // 结束 } ================================================ FILE: 1.x/Chapter6-1-1/src/main/resources/application.properties ================================================ spring.application.name=statemachine ================================================ FILE: 1.x/Chapter6-2-1/pom.xml ================================================ 4.0.0 com.didispace Chapter6-2-1 1.0.0 jar Chapter6-2-1 org.springframework.boot spring-boot-starter-parent 1.5.3.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-maven-plugin pl.project13.maven git-commit-id-plugin 2.1.15 revision ${project.basedir}/.git ================================================ FILE: 1.x/Chapter6-2-1/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter6-2-1/src/main/java/com/didispace/web/HelloController.java ================================================ package com.didispace.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } } ================================================ FILE: 1.x/Chapter6-2-1/src/main/resources/application.properties ================================================ #management.info.git.mode=full ================================================ FILE: 1.x/Chapter6-2-1/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Test; import org.springframework.boot.test.context.SpringBootTest; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootTest public class ApplicationTests { @Test public void test1() throws Exception { } } ================================================ FILE: 1.x/Chapter9-1-1/compute-service/pom.xml ================================================ 4.0.0 com.didispace compute-service 1.0.0 jar compute-service Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class ComputeServiceApplication { public static void main(String[] args) { new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/web/ComputeController.java ================================================ package com.didispace.web; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ComputeController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/add" ,method = RequestMethod.GET) public Integer add(@RequestParam Integer a, @RequestParam Integer b) { ServiceInstance instance = client.getLocalServiceInstance(); Integer r = a + b; logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r); return r; } } ================================================ FILE: 1.x/Chapter9-1-1/compute-service/src/main/resources/application.properties ================================================ spring.application.name=compute-service server.port=2222 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-1/compute-service/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.ComputeController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new ComputeController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter9-1-1/eureka-server/pom.xml ================================================ 4.0.0 com.didispace eureka-server 1.0.0 jar eureka-server Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-1/eureka-server/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-1/eureka-server/src/main/resources/application.properties ================================================ server.port=1111 #eureka.instance.hostname=localhost eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/ ================================================ FILE: 1.x/Chapter9-1-2/eureka-feign/pom.xml ================================================ 4.0.0 com.didispace eureka-feign 1.0.0 jar eureka-feign Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-feign org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/FeignApplication.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class, args); } } ================================================ FILE: 1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java ================================================ package com.didispace.service; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @FeignClient("compute-service") public interface ComputeClient { @RequestMapping(method = RequestMethod.GET, value = "/add") Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b); } ================================================ FILE: 1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java ================================================ package com.didispace.web; import com.didispace.service.ComputeClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class ConsumerController { @Autowired ComputeClient computeClient; @RequestMapping(value = "/add", method = RequestMethod.GET) public Integer add() { return computeClient.add(10, 20); } } ================================================ FILE: 1.x/Chapter9-1-2/eureka-feign/src/main/resources/application.properties ================================================ spring.application.name=feign-consumer server.port=3333 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-2/eureka-ribbon/pom.xml ================================================ 4.0.0 com.didispace eureka-ribbon 1.0.0 jar eureka-ribbon Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-ribbon org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient public class RibbonApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonApplication.class, args); } } ================================================ FILE: 1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java ================================================ package com.didispace.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class ConsumerController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/add", method = RequestMethod.GET) public String add() { return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody(); } } ================================================ FILE: 1.x/Chapter9-1-2/eureka-ribbon/src/main/resources/application.properties ================================================ spring.application.name=ribbon-consumer server.port=3333 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-3/compute-service/pom.xml ================================================ 4.0.0 com.didispace compute-service 1.0.0 jar compute-service Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class ComputeServiceApplication { public static void main(String[] args) { new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/web/ComputeController.java ================================================ package com.didispace.web; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ComputeController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/add" ,method = RequestMethod.GET) public Integer add(@RequestParam Integer a, @RequestParam Integer b) { ServiceInstance instance = client.getLocalServiceInstance(); Integer r = a + b; logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r); return r; } } ================================================ FILE: 1.x/Chapter9-1-3/compute-service/src/main/resources/application.properties ================================================ spring.application.name=compute-service server.port=2222 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-3/compute-service/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.ComputeController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new ComputeController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-feign/pom.xml ================================================ 4.0.0 com.didispace eureka-feign 1.0.0 jar eureka-feign Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-feign org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/FeignApplication.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class, args); } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java ================================================ package com.didispace.service; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(value = "compute-service", fallback = ComputeClientHystrix.class) public interface ComputeClient { @RequestMapping(method = RequestMethod.GET, value = "/add") Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b); } ================================================ FILE: 1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClientHystrix.java ================================================ package com.didispace.service; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestParam; @Component public class ComputeClientHystrix implements ComputeClient { @Override public Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) { return -9999; } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java ================================================ package com.didispace.web; import com.didispace.service.ComputeClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class ConsumerController { @Autowired ComputeClient computeClient; @RequestMapping(value = "/add", method = RequestMethod.GET) public Integer add() { return computeClient.add(10, 20); } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-ribbon/pom.xml ================================================ 4.0.0 com.didispace eureka-ribbon 1.0.0 jar eureka-ribbon Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-hystrix org.springframework.cloud spring-cloud-starter-ribbon org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public class RibbonApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonApplication.class, args); } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/service/ComputeService.java ================================================ package com.didispace.service; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class ComputeService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "addServiceFallback") public String addService() { return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody(); } public String addServiceFallback() { return "error"; } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java ================================================ package com.didispace.web; import com.didispace.service.ComputeService; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.Map; @RestController public class ConsumerController { @Autowired private ComputeService computeService; @RequestMapping(value = "/add", method = RequestMethod.GET) public String add() { return computeService.addService(); } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-server/pom.xml ================================================ 4.0.0 com.didispace eureka-server 1.0.0 jar eureka-server Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-3/eureka-server/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-3/eureka-server/src/main/resources/application.properties ================================================ server.port=1111 #eureka.instance.hostname=localhost eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/ ================================================ FILE: 1.x/Chapter9-1-4/config-client/pom.xml ================================================ 4.0.0 com.didispace config-client 1.0.0 jar config-client Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-config org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/web/TestController.java ================================================ package com.didispace.web; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RefreshScope @RestController class TestController { @Value("${from}") private String from; @RequestMapping("/from") public String from() { return this.from; } public void setFrom(String from) { this.from = from; } public String getFrom() { return from; } } ================================================ FILE: 1.x/Chapter9-1-4/config-client/src/main/resources/bootstrap.properties ================================================ spring.application.name=didispace spring.cloud.config.profile=dev spring.cloud.config.uri=http://localhost:7001/ server.port=7002 ================================================ FILE: 1.x/Chapter9-1-4/config-repo/didispace-dev.properties ================================================ from=git-dev-1.0 ================================================ FILE: 1.x/Chapter9-1-4/config-repo/didispace-prod.properties ================================================ from=git-prod-1.0 ================================================ FILE: 1.x/Chapter9-1-4/config-repo/didispace-test.properties ================================================ from=git-test-1.0 ================================================ FILE: 1.x/Chapter9-1-4/config-repo/didispace.properties ================================================ from=git-default-1.0 ================================================ FILE: 1.x/Chapter9-1-4/config-server/pom.xml ================================================ 4.0.0 com.didispace config-server 1.0.0 jar config-server Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-config-server org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-4/config-server/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.config.server.EnableConfigServer; @EnableConfigServer @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-4/config-server/src/main/resources/application.properties ================================================ spring.application.name=config-server server.port=7001 # git spring.cloud.config.server.git.uri=http://git.oschina.net/didispace/SpringBoot-Learning/ spring.cloud.config.server.git.searchPaths=Chapter9-1-4/config-repo spring.cloud.config.server.git.username=username spring.cloud.config.server.git.password=password # spring.profiles.active=native ================================================ FILE: 1.x/Chapter9-1-4/config-server/src/main/resources/didispace-dev.properties ================================================ from=local-dev ================================================ FILE: 1.x/Chapter9-1-4/config-server/src/main/resources/didispace-prod.properties ================================================ from=local-prod ================================================ FILE: 1.x/Chapter9-1-4/config-server/src/main/resources/didispace-test.properties ================================================ from=local-test ================================================ FILE: 1.x/Chapter9-1-4/config-server/src/main/resources/didispace.properties ================================================ from=local ================================================ FILE: 1.x/Chapter9-1-5/api-gateway/pom.xml ================================================ 4.0.0 com.didispace api-gateway 1.0.0 jar api-gateway Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-zuul org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import com.didispace.filter.AccessFilter; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.SpringCloudApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.context.annotation.Bean; @EnableZuulProxy @SpringCloudApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } @Bean public AccessFilter accessFilter() { return new AccessFilter(); } } ================================================ FILE: 1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/filter/AccessFilter.java ================================================ package com.didispace.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; public class AccessFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(AccessFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("accessToken"); if(accessToken == null) { log.warn("access token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); return null; } log.info("access token ok"); return null; } } ================================================ FILE: 1.x/Chapter9-1-5/api-gateway/src/main/resources/application.properties ================================================ spring.application.name=api-gateway server.port=5555 # routes to serviceId zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.serviceId=service-A zuul.routes.api-b.path=/api-b/** zuul.routes.api-b.serviceId=service-B # routes to url zuul.routes.api-a-url.path=/api-a-url/** zuul.routes.api-a-url.url=http://localhost:2222/ eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-5/eureka-server/pom.xml ================================================ 4.0.0 com.didispace eureka-server 1.0.0 jar eureka-server Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-5/eureka-server/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-5/eureka-server/src/main/resources/application.properties ================================================ server.port=1111 #eureka.instance.hostname=localhost eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/ ================================================ FILE: 1.x/Chapter9-1-5/service-A/pom.xml ================================================ 4.0.0 com.didispace service-A 1.0.0 jar service-A Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/ComputeServiceApplication.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class ComputeServiceApplication { public static void main(String[] args) { new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/web/ComputeController.java ================================================ package com.didispace.web; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ComputeController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/add" ,method = RequestMethod.GET) public String add(@RequestParam Integer a, @RequestParam Integer b) { ServiceInstance instance = client.getLocalServiceInstance(); Integer r = a + b; logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r); return "From Service-A, Result is " + r; } } ================================================ FILE: 1.x/Chapter9-1-5/service-A/src/main/resources/application.properties ================================================ spring.application.name=service-A server.port=2222 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-5/service-A/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.ComputeController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new ComputeController()).build(); } @Test public void getHello() throws Exception { } } ================================================ FILE: 1.x/Chapter9-1-5/service-B/pom.xml ================================================ 4.0.0 com.didispace service-B 1.0.0 jar service-B Spring Cloud project org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.cloud spring-cloud-starter-eureka org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies Brixton.RELEASE pom import org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/ComputeServiceApplication.java ================================================ package com.didispace; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class ComputeServiceApplication { public static void main(String[] args) { new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args); } } ================================================ FILE: 1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/web/ComputeController.java ================================================ package com.didispace.web; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ComputeController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/add" ,method = RequestMethod.GET) public String add(@RequestParam Integer a, @RequestParam Integer b) { ServiceInstance instance = client.getLocalServiceInstance(); Integer r = a + b; logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r); return "From Service-B, Result is " + r; } } ================================================ FILE: 1.x/Chapter9-1-5/service-B/src/main/resources/application.properties ================================================ spring.application.name=service-B server.port=3333 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ ================================================ FILE: 1.x/Chapter9-1-5/service-B/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.web.ComputeController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class ApplicationTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new ComputeController()).build(); } @Test public void getHello() throws Exception { } } ================================================ FILE: 1.x/Chapter9-2-1/compute-service/pom.xml ================================================ 4.0.0 com.didispace compute-service 1.0.0 jar compute-service Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test com.alibaba dubbo 2.5.3 spring org.springframework org.apache.zookeeper zookeeper 3.4.6 org.slf4j slf4j-log4j12 log4j log4j com.github.sgroschupf zkclient 0.1 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ImportResource; import java.util.concurrent.CountDownLatch; @SpringBootApplication @ImportResource({"classpath:dubbo.xml"}) public class Application { private static final Logger logger = Logger.getLogger(Application.class); @Bean public CountDownLatch closeLatch() { return new CountDownLatch(1); } public static void main(String[] args) throws InterruptedException { ApplicationContext ctx = SpringApplication.run(Application.class, args); logger.info("项目启动!"); CountDownLatch closeLatch = ctx.getBean(CountDownLatch.class); closeLatch.await(); } } ================================================ FILE: 1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/ComputeService.java ================================================ package com.didispace.service; /** * Created by zhaiyc on 2016/7/14. */ public interface ComputeService { Integer add(int a, int b); } ================================================ FILE: 1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java ================================================ package com.didispace.service.impl; import com.didispace.service.ComputeService; /** * Created by zhaiyc on 2016/7/14. */ public class ComputeServiceImpl implements ComputeService { @Override public Integer add(int a, int b) { return a + b; } } ================================================ FILE: 1.x/Chapter9-2-1/compute-service/src/main/resources/application.properties ================================================ #ZooKeeper dubbo.registry.address=localhost:2181 logging.level.root=DEBUG ================================================ FILE: 1.x/Chapter9-2-1/compute-service/src/main/resources/dubbo.xml ================================================ ================================================ FILE: 1.x/Chapter9-2-1/compute-service/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Before public void setUp() throws Exception { } @Test public void getHello() throws Exception { } } ================================================ FILE: 1.x/Chapter9-2-1/consumer/pom.xml ================================================ 4.0.0 com.didispace consumer 1.0.0 jar consumer Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test com.alibaba dubbo 2.5.3 spring org.springframework org.apache.zookeeper zookeeper 3.4.6 org.slf4j slf4j-log4j12 log4j log4j com.github.sgroschupf zkclient 0.1 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ImportResource; import java.util.concurrent.CountDownLatch; @SpringBootApplication @ImportResource({"classpath:dubbo.xml"}) public class Application { public static void main(String[] args) throws InterruptedException { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/service/ComputeService.java ================================================ package com.didispace.service; /** * Created by zhaiyc on 2016/7/14. */ public interface ComputeService { Integer add(int a, int b); } ================================================ FILE: 1.x/Chapter9-2-1/consumer/src/main/resources/application.properties ================================================ #ZooKeeper dubbo.registry.address=localhost:2181 logging.level.root=DEBUG ================================================ FILE: 1.x/Chapter9-2-1/consumer/src/main/resources/dubbo.xml ================================================ ================================================ FILE: 1.x/Chapter9-2-1/consumer/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.service.ComputeService; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Autowired ComputeService computeService; @Test public void testAdd() throws Exception { Assert.assertEquals("compute-service:add", new Integer(3), computeService.add(1, 2)); } } ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api/pom.xml ================================================ 4.0.0 com.didispace compute-service 1.0-SNAPSHOT compute-api compute-api jar ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/ComputeService.java ================================================ package com.didispace.service; /** * Created by zhaiyc on 2016/7/14. */ public interface ComputeService { Integer add(int a, int b); } ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java ================================================ package com.didispace.service.impl; import com.didispace.service.ComputeService; /** * Created by zhaiyc on 2016/7/14. */ public class ComputeServiceImpl implements ComputeService { @Override public Integer add(int a, int b) { return a + b; } } ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api-server/pom.xml ================================================ 4.0.0 com.didispace compute-api-server 1.0.0 jar compute-api-server Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test com.didispace compute-api 1.0-SNAPSHOT com.alibaba dubbo 2.5.3 spring org.springframework org.apache.zookeeper zookeeper 3.4.6 org.slf4j slf4j-log4j12 log4j log4j com.github.sgroschupf zkclient 0.1 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.apache.log4j.Logger; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ImportResource; import java.util.concurrent.CountDownLatch; @SpringBootApplication @ImportResource({"classpath:dubbo.xml"}) public class Application { private static final Logger logger = Logger.getLogger(Application.class); @Bean public CountDownLatch closeLatch() { return new CountDownLatch(1); } public static void main(String[] args) throws InterruptedException { ApplicationContext ctx = SpringApplication.run(Application.class, args); logger.info("项目启动!"); CountDownLatch closeLatch = ctx.getBean(CountDownLatch.class); closeLatch.await(); } } ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java ================================================ package com.didispace.service.impl; import com.didispace.service.ComputeService; /** * Created by zhaiyc on 2016/7/14. */ public class ComputeServiceImpl implements ComputeService { @Override public Integer add(int a, int b) { return a + b; } } ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/application.properties ================================================ #ZooKeeper dubbo.registry.address=localhost:2181 logging.level.root=DEBUG ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/dubbo.xml ================================================ ================================================ FILE: 1.x/Chapter9-2-2/compute-service/compute-api-server/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Before public void setUp() throws Exception { } @Test public void getHello() throws Exception { } } ================================================ FILE: 1.x/Chapter9-2-2/compute-service/pom.xml ================================================ 4.0.0 com.didispace compute-service pom 1.0-SNAPSHOT compute-api compute-api-server true UTF-8 1.7 1.7 1.7 ================================================ FILE: 1.x/Chapter9-2-2/consumer/pom.xml ================================================ 4.0.0 com.didispace consumer 1.0.0 jar consumer Spring Boot project org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test com.didispace compute-api 1.0-SNAPSHOT com.alibaba dubbo 2.5.3 spring org.springframework org.apache.zookeeper zookeeper 3.4.6 org.slf4j slf4j-log4j12 log4j log4j com.github.sgroschupf zkclient 0.1 org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 1.x/Chapter9-2-2/consumer/src/main/java/com/didispace/Application.java ================================================ package com.didispace; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; @SpringBootApplication @ImportResource({"classpath:dubbo.xml"}) public class Application { public static void main(String[] args) throws InterruptedException { SpringApplication.run(Application.class, args); } } ================================================ FILE: 1.x/Chapter9-2-2/consumer/src/main/resources/application.properties ================================================ #ZooKeeper dubbo.registry.address=localhost:2181 logging.level.root=INFO ================================================ FILE: 1.x/Chapter9-2-2/consumer/src/main/resources/dubbo.xml ================================================ ================================================ FILE: 1.x/Chapter9-2-2/consumer/src/test/java/com/didispace/ApplicationTests.java ================================================ package com.didispace; import com.didispace.service.ComputeService; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Autowired private ComputeService computeService; @Test public void testAdd() throws Exception { Assert.assertEquals("compute-service:add", new Integer(3), computeService.add(1, 2)); } } ================================================ FILE: 1.x/README.md ================================================ 该目录下为Spring Boot 1.x版本的教程,因为版本落后,**后续不再继续更新**。 推荐下面的2.x版本,还在持续更新哦! - 教程汇总(1.x版本):[《Spring Boot基础教程》](https://blog.didispace.com/spring-boot-learning-1x/) - 教程汇总(2.x版本):[《Spring Boot基础教程》](https://blog.didispace.com/spring-boot-learning-2x/) Spring Boot 2.x版本的教程可在`2.x`目录下查看。 ## 教程目录(1.x版本) 本教程版本基于Spring Boot 1.3.x - 1.5.x,部分内容可能会有出入。如果您发现问题,首先看版本是否一致。如果还有问题,可以提Issue指出。 如果您要学习Spring Boot 2.x版本,可以切换到2.x分支学习,本教程正在连载2.x版本的最新教程,如果您觉得内容不错,Star关注我吧! #### 快速入门 - [Spring Cloud Alibaba与Spring Boot、Spring Cloud之间不得不说的版本关系](http://blog.didispace.com/spring-cloud-alibaba-version/) - chapter1:[基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API](http://blog.didispace.com/spring-boot-learning-1/) - [使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程](http://blog.didispace.com/spring-initializr-in-intellij/) > 提示:我们在学习Spring Boot、Spring Cloud的时候,一定要知道它们的版本关系,以避免不必要的困恼。 #### 工程配置 - chapter2-1-1:[配置文件详解:自定义属性、随机数、多环境配置等](http://blog.didispace.com/springbootproperties/) - chapter2-2-1:[2.0 新特性(一):配置绑定全解析](http://blog.didispace.com/Spring-Boot-2-0-feature-1-relaxed-binding-2/) - chapter2-1-2:[2.0 新特性(二):新增事件ApplicationStartedEvent](http://blog.didispace.com/Spring-Boot-2-0-feature-2-ApplicationStartedEvent/) #### Web开发 - chapter3-1-1:[构建一个较为复杂的RESTful API以及单元测试](http://blog.didispace.com/springbootrestfulapi/) - chapter3-1-2:[使用Thymeleaf模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-3:[使用Freemarker模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-4:[使用Velocity模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-5:[使用Swagger2构建RESTful API](http://blog.didispace.com/springbootswagger2/) - chapter3-1-6:[统一异常处理](http://blog.didispace.com/springbootexception/) - chapter3-1-7:[使用Java 8中LocalDate等时间日期类的问题解决](http://blog.didispace.com/Spring-Boot-And-Feign-Use-localdate/) - chapter3-1-8:[扩展XML请求和响应的支持](http://blog.didispace.com/spring-boot-xml-httpmessageconverter) #### 数据访问 - chapter3-2-1:[使用JdbcTemplate](http://blog.didispace.com/springbootdata1/) - chapter3-2-2:[使用Spring-data-jpa简化数据访问层(推荐)](http://blog.didispace.com/springbootdata2/) - chapter3-2-3:[多数据源配置(一):JdbcTemplate](http://blog.didispace.com/springbootmultidatasource/) - chapter3-2-4:[多数据源配置(二):Spring-data-jpa](http://blog.didispace.com/springbootmultidatasource/) - chapter3-2-5:[使用NoSQL数据库(一):Redis](http://blog.didispace.com/springbootredis/) - chapter3-2-6:[使用NoSQL数据库(二):MongoDB](http://blog.didispace.com/springbootmongodb/) - chapter3-2-7:[整合MyBatis](http://blog.didispace.com/springbootmybatis/) - chapter3-2-8:[MyBatis注解配置详解](http://blog.didispace.com/mybatisinfo/) - chapter3-2-9:[使用Flyway来管理数据库版本](http://blog.didispace.com/spring-boot-flyway-db-version/) - chapter3-2-10:[使用LDAP来统一管理用户信息](http://blog.didispace.com/spring-boot-ldap-user/) - chapter3-2-11:[Spring Boot中增强对MongoDB的配置(连接池等)](http://blog.didispace.com/springbootmongodb-plus/) #### 事务管理 - chapter3-3-1:[使用事务管理](http://blog.didispace.com/springboottransactional/) - chapter3-3-2:[分布式事务(未完成)] #### 其他内容 - chapter4-1-1:[使用@Scheduled创建定时任务](http://blog.didispace.com/springbootscheduled/) - chapter4-1-2:[使用@Async实现异步调用](http://blog.didispace.com/springbootasync/) - chapter4-1-3:[使用@Async实现异步调用:自定义线程池](http://blog.didispace.com/springbootasync-2/) - chapter4-1-4:[使用@Async实现异步调用:资源优雅关闭](http://blog.didispace.com/springbootasync-3/) - chapter4-1-5:[使用@Async实现异步调用:使用Future以及定义超时](http://blog.didispace.com/springbootasync-4/) #### 日志管理 - chapter4-2-1:[默认日志的配置](http://blog.didispace.com/springbootlog/) - chapter4-2-2:[使用log4j记录日志](http://blog.didispace.com/springbootlog4j/) - chapter4-2-3:[对log4j进行多环境不同日志级别的控制](http://blog.didispace.com/springbootlog4jmuilt/) - chapter4-2-4:[使用AOP统一处理Web请求日志](http://blog.didispace.com/springbootaoplog/) - chapter4-2-5:[使用log4j记录日志到MongoDB](http://blog.didispace.com/springbootlog4jmongodb/) - chapter4-2-6:[Spring Boot 1.5.x新特性:动态修改日志级别](http://blog.didispace.com/spring-boot-1-5-x-feature-1/)] #### 安全管理 - chapter4-3-1:[使用Spring Security](http://blog.didispace.com/springbootsecurity/) - chapter4-3-2:[使用Spring Session(未完成)] #### 缓存支持 - chapter4-4-1:[注解配置与EhCache使用](http://blog.didispace.com/springbootcache1/) - chapter4-4-2:[使用Redis做集中式缓存](http://blog.didispace.com/springbootcache2/) #### 邮件发送 - chapter4-5-1:[实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件](http://blog.didispace.com/springbootmailsender/) #### 消息服务 - chapter5-1-1:[JMS(未完成)] - chapter5-2-1:[Spring Boot中使用RabbitMQ](http://blog.didispace.com/spring-boot-rabbitmq/) #### 其他功能 - chapter6-1-1:[使用Spring StateMachine框架实现状态机](http://blog.didispace.com/spring-statemachine/) - [Spring Boot Actuator监控端点小结](http://blog.didispace.com/spring-boot-actuator-1/) - [在传统Spring应用中使用spring-boot-actuator模块提供监控端点](http://blog.didispace.com/spring-boot-actuator-without-boot/) - [Spring Boot应用的后台运行配置](http://blog.didispace.com/spring-boot-run-backend/) - [Spring Boot自定义Banner](http://blog.didispace.com/spring-boot-banner/) #### Dubbo进行服务治理 - chapter9-2-1:[Spring Boot中使用Dubbo进行服务治理](https://gitee.com/didispace/SpringBoot-Learning/tree/master/Chapter9-2-1) - chapter9-2-2:[Spring Boot与Dubbo中管理服务依赖](https://gitee.com/didispace/SpringBoot-Learning/tree/master/Chapter9-2-2) ## 推荐内容 - [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容 - [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活 - [GitHub](https://github.com/dyc87112/SpringBoot-Learning):Star支持一下呗 - [Gitee](https://gitee.com/didispace/SpringBoot-Learning):Star支持一下呗 - [Spring问答社区](http://www.spring4all.com/):如果您有什么问题,可以去这里发帖 - [Spring Boot基础教程](http://blog.didispace.com/Spring-Boot%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/):全网Star最多的免费Spring Boot基础教程 - [Spring Cloud基础教程](http://blog.didispace.com/Spring-Cloud%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/):全网最早最全的免费Spring Cloud基础教程 ## 我的公众号 ================================================ FILE: 1.x/README_zh.md ================================================ 该目录下为Spring Boot 1.x版本的教程,因为版本落后,**后续不再继续更新**。 推荐下面的2.x版本,还在持续更新哦! - 教程汇总(1.x版本):[《Spring Boot基础教程》](https://blog.didispace.com/spring-boot-learning-1x/) - 教程汇总(2.x版本):[《Spring Boot基础教程》](https://blog.didispace.com/spring-boot-learning-2x/) Spring Boot 2.x版本的教程可在`2.x`目录下查看。 ## 教程目录(1.x版本) 本教程版本基于Spring Boot 1.3.x - 1.5.x,部分内容可能会有出入。如果您发现问题,首先看版本是否一致。如果还有问题,可以提Issue指出。 如果您要学习Spring Boot 2.x版本,可以切换到2.x分支学习,本教程正在连载2.x版本的最新教程,如果您觉得内容不错,Star关注我吧! #### 快速入门 - [Spring Cloud Alibaba与Spring Boot、Spring Cloud之间不得不说的版本关系](http://blog.didispace.com/spring-cloud-alibaba-version/) - chapter1:[基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API](http://blog.didispace.com/spring-boot-learning-1/) - [使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程](http://blog.didispace.com/spring-initializr-in-intellij/) > 提示:我们在学习Spring Boot、Spring Cloud的时候,一定要知道它们的版本关系,以避免不必要的困恼。 #### 工程配置 - chapter2-1-1:[配置文件详解:自定义属性、随机数、多环境配置等](http://blog.didispace.com/springbootproperties/) - chapter2-2-1:[2.0 新特性(一):配置绑定全解析](http://blog.didispace.com/Spring-Boot-2-0-feature-1-relaxed-binding-2/) - chapter2-1-2:[2.0 新特性(二):新增事件ApplicationStartedEvent](http://blog.didispace.com/Spring-Boot-2-0-feature-2-ApplicationStartedEvent/) #### Web开发 - chapter3-1-1:[构建一个较为复杂的RESTful API以及单元测试](http://blog.didispace.com/springbootrestfulapi/) - chapter3-1-2:[使用Thymeleaf模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-3:[使用Freemarker模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-4:[使用Velocity模板引擎渲染web视图](http://blog.didispace.com/springbootweb/) - chapter3-1-5:[使用Swagger2构建RESTful API](http://blog.didispace.com/springbootswagger2/) - chapter3-1-6:[统一异常处理](http://blog.didispace.com/springbootexception/) - chapter3-1-7:[使用Java 8中LocalDate等时间日期类的问题解决](http://blog.didispace.com/Spring-Boot-And-Feign-Use-localdate/) - chapter3-1-8:[扩展XML请求和响应的支持](http://blog.didispace.com/spring-boot-xml-httpmessageconverter) #### 数据访问 - chapter3-2-1:[使用JdbcTemplate](http://blog.didispace.com/springbootdata1/) - chapter3-2-2:[使用Spring-data-jpa简化数据访问层(推荐)](http://blog.didispace.com/springbootdata2/) - chapter3-2-3:[多数据源配置(一):JdbcTemplate](http://blog.didispace.com/springbootmultidatasource/) - chapter3-2-4:[多数据源配置(二):Spring-data-jpa](http://blog.didispace.com/springbootmultidatasource/) - chapter3-2-5:[使用NoSQL数据库(一):Redis](http://blog.didispace.com/springbootredis/) - chapter3-2-6:[使用NoSQL数据库(二):MongoDB](http://blog.didispace.com/springbootmongodb/) - chapter3-2-7:[整合MyBatis](http://blog.didispace.com/springbootmybatis/) - chapter3-2-8:[MyBatis注解配置详解](http://blog.didispace.com/mybatisinfo/) - chapter3-2-9:[使用Flyway来管理数据库版本](http://blog.didispace.com/spring-boot-flyway-db-version/) - chapter3-2-10:[使用LDAP来统一管理用户信息](http://blog.didispace.com/spring-boot-ldap-user/) - chapter3-2-11:[Spring Boot中增强对MongoDB的配置(连接池等)](http://blog.didispace.com/springbootmongodb-plus/) #### 事务管理 - chapter3-3-1:[使用事务管理](http://blog.didispace.com/springboottransactional/) - chapter3-3-2:[分布式事务(未完成)] #### 其他内容 - chapter4-1-1:[使用@Scheduled创建定时任务](http://blog.didispace.com/springbootscheduled/) - chapter4-1-2:[使用@Async实现异步调用](http://blog.didispace.com/springbootasync/) - chapter4-1-3:[使用@Async实现异步调用:自定义线程池](http://blog.didispace.com/springbootasync-2/) - chapter4-1-4:[使用@Async实现异步调用:资源优雅关闭](http://blog.didispace.com/springbootasync-3/) - chapter4-1-5:[使用@Async实现异步调用:使用Future以及定义超时](http://blog.didispace.com/springbootasync-4/) #### 日志管理 - chapter4-2-1:[默认日志的配置](http://blog.didispace.com/springbootlog/) - chapter4-2-2:[使用log4j记录日志](http://blog.didispace.com/springbootlog4j/) - chapter4-2-3:[对log4j进行多环境不同日志级别的控制](http://blog.didispace.com/springbootlog4jmuilt/) - chapter4-2-4:[使用AOP统一处理Web请求日志](http://blog.didispace.com/springbootaoplog/) - chapter4-2-5:[使用log4j记录日志到MongoDB](http://blog.didispace.com/springbootlog4jmongodb/) - chapter4-2-6:[Spring Boot 1.5.x新特性:动态修改日志级别](http://blog.didispace.com/spring-boot-1-5-x-feature-1/)] #### 安全管理 - chapter4-3-1:[使用Spring Security](http://blog.didispace.com/springbootsecurity/) - chapter4-3-2:[使用Spring Session(未完成)] #### 缓存支持 - chapter4-4-1:[注解配置与EhCache使用](http://blog.didispace.com/springbootcache1/) - chapter4-4-2:[使用Redis做集中式缓存](http://blog.didispace.com/springbootcache2/) #### 邮件发送 - chapter4-5-1:[实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件](http://blog.didispace.com/springbootmailsender/) #### 消息服务 - chapter5-1-1:[JMS(未完成)] - chapter5-2-1:[Spring Boot中使用RabbitMQ](http://blog.didispace.com/spring-boot-rabbitmq/) #### 其他功能 - chapter6-1-1:[使用Spring StateMachine框架实现状态机](http://blog.didispace.com/spring-statemachine/) - [Spring Boot Actuator监控端点小结](http://blog.didispace.com/spring-boot-actuator-1/) - [在传统Spring应用中使用spring-boot-actuator模块提供监控端点](http://blog.didispace.com/spring-boot-actuator-without-boot/) - [Spring Boot应用的后台运行配置](http://blog.didispace.com/spring-boot-run-backend/) - [Spring Boot自定义Banner](http://blog.didispace.com/spring-boot-banner/) #### Dubbo进行服务治理 - chapter9-2-1:[Spring Boot中使用Dubbo进行服务治理](https://gitee.com/didispace/SpringBoot-Learning/tree/master/Chapter9-2-1) - chapter9-2-2:[Spring Boot与Dubbo中管理服务依赖](https://gitee.com/didispace/SpringBoot-Learning/tree/master/Chapter9-2-2) ## 推荐内容 - [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容 - [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活 - [GitHub](https://github.com/dyc87112/SpringBoot-Learning):Star支持一下呗 - [Gitee](https://gitee.com/didispace/SpringBoot-Learning):Star支持一下呗 - [Spring问答社区](http://www.spring4all.com/):如果您有什么问题,可以去这里发帖 - [Spring Boot基础教程](http://blog.didispace.com/Spring-Boot%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/):全网Star最多的免费Spring Boot基础教程 - [Spring Cloud基础教程](http://blog.didispace.com/Spring-Cloud%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/):全网最早最全的免费Spring Cloud基础教程 ## 我的公众号 ================================================ FILE: 2.x/README.md ================================================ # Spring Boot基础教程(2.x版本) 本项目内容为[《Spring Boot基础教程》](http://blog.didispace.com/spring-boot-learning-2x/)的程序样例。 **专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程! **加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长 **Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章 **如何支持**: 1. 关注我的公众号”**程序猿DD**“ 2. 点个`Star`并`Follow`我 3. 把该仓库分享给更多的朋友 ## 教程目录(2.x版本) 本教程内容持续更新连载中!**Star关注**支持一下,随时获得更新信息! ### 快速入门 - [Spring Boot 2.x基础教程:版本关系](http://blog.didispace.com/spring-cloud-alibaba-version/) - [Spring Boot 2.x基础教程:快速入门](http://blog.didispace.com/spring-boot-learning-21-1-1/) - [Spring Boot 2.x基础教程:工程结构推荐](http://blog.didispace.com/spring-boot-learning-21-1-2/) ### 配置详解 - [Spring Boot 2.x基础教程:配置文件详解](http://blog.didispace.com/spring-boot-learning-21-1-3/) - [Spring Boot 2.x基础教程:2.4版本前后的多环境配置变化](http://blog.didispace.com/spring-boot-learning-24-1-4/) - [Spring Boot 2.x基础教程:2.4版本前后的分组配置变化](http://blog.didispace.com/spring-boot-learning-24-1-5/) - [Spring Boot 2.x基础教程:配置元数据的应用 ](http://blog.didispace.com/spring-boot-learning-24-1-6/) - [Spring Boot 2.x基础教程:加密配置中的敏感信息](http://blog.didispace.com/spring-boot-learning-2-1-5/) ### API开发 - [Spring Boot 2.x基础教程:构建RESTful API与单元测试](http://blog.didispace.com/spring-boot-learning-21-2-1/) - [Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档](http://blog.didispace.com/spring-boot-learning-21-2-2/) - [Spring Boot 2.x基础教程:JSR-303实现请求参数校验](http://blog.didispace.com/spring-boot-learning-21-2-3/) - [Spring Boot 2.x基础教程:Swagger接口分类与各元素排序问题详解](http://blog.didispace.com/spring-boot-learning-21-2-4/) - [Spring Boot 2.x基础教程:Swagger静态文档的生成](http://blog.didispace.com/spring-boot-learning-21-2-5/) - [Spring Boot 2.x基础教程:找回启动日志中的请求路径列表](http://blog.didispace.com/spring-boot-learning-21-2-6/) - [Spring Boot 2.x基础教程:使用SpringFox 3生成Swagger文档](http://blog.didispace.com/spring-boot-learning-21-2-7/) - [Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应](http://blog.didispace.com/spring-boot-learning-21-2-8/) ### 数据访问 **关系型数据库** - [Spring Boot 2.x基础教程:使用JdbcTemplate访问MySQL数据库](http://blog.didispace.com/spring-boot-learning-21-3-1/) - [Spring Boot 2.x基础教程:默认数据源Hikari的配置详解](http://blog.didispace.com/spring-boot-learning-21-3-2/) - [Spring Boot 2.x基础教程:使用国产数据库连接池Druid](http://blog.didispace.com/spring-boot-learning-21-3-3/) - [Spring Boot 2.x基础教程:使用Spring Data JPA访问MySQL](http://blog.didispace.com/spring-boot-learning-21-3-4/) - [Spring Boot 2.x基础教程:使用MyBatis访问MySQL](http://blog.didispace.com/spring-boot-learning-21-3-5/) - [Spring Boot 2.x基础教程:使用MyBatis的XML配置方式](http://blog.didispace.com/spring-boot-learning-21-3-6/) - [Spring Boot 2.x基础教程:JdbcTemplate的多数据源配置](http://blog.didispace.com/spring-boot-learning-21-3-7/) - [Spring Boot 2.x基础教程:Spring Data JPA的多数据源配置](http://blog.didispace.com/spring-boot-learning-21-3-8/) - [Spring Boot 2.x基础教程:MyBatis的多数据源配置](http://blog.didispace.com/spring-boot-learning-21-3-9/) - [Spring Boot 2.x基础教程:事务管理入门](http://blog.didispace.com/spring-boot-learning-21-3-10/) - [Spring Boot 2.x基础教程:使用Flyway管理数据库版本](http://blog.didispace.com/spring-boot-learning-24-3-11/) - [Spring Boot 2.x基础教程:使用JTA实现多数据源的事务管理](http://blog.didispace.com/spring-boot-learning-24-3-12/) - [Spring Boot 2.x基础教程:2.5版本后数据脚本初始化的变动](http://blog.didispace.com/spring-boot-learning-25-3-13/) **加速利器:各种缓存的使用** - [Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解](http://blog.didispace.com/spring-boot-learning-21-5-1/) - [Spring Boot 2.x基础教程:EhCache缓存的使用](http://blog.didispace.com/spring-boot-learning-21-5-2/) - [Spring Boot 2.x基础教程:使用EhCache缓存集群](http://blog.didispace.com/spring-boot-learning-21-5-3/) - [Spring Boot 2.x基础教程:使用集中式缓存Redis](http://blog.didispace.com/spring-boot-learning-21-5-4/) - [Spring Boot 2.x基础教程:使用Redis的发布订阅功能](http://blog.didispace.com/spring-boot-learning-25-5-5/) **其他常见存储的使用** - [Spring Boot 2.x基础教程:使用MongoDB](http://blog.didispace.com/spring-boot-learning-24-6-1/) - [Spring Boot 2.x基础教程:使用LDAP来管理用户与组织数据](http://blog.didispace.com/spring-boot-learning-24-6-2/) - [Spring Boot 2.x基础教程:使用时序数据库InfluxDB](http://blog.didispace.com/spring-boot-learning-2-6-3/) - [Spring Boot 2.x基础教程:使用PostgreSQL](http://blog.didispace.com/spring-boot-learning-2-6-4/) ### Web开发 - [Spring Boot 2.x基础教程:使用 Thymeleaf开发Web页面](http://blog.didispace.com/spring-boot-learning-21-4-1/) - [Spring Boot 2.x基础教程:使用 ECharts 绘制各种华丽的数据图表](http://blog.didispace.com/spring-boot-learning-21-4-2/) - [Spring Boot 2.x基础教程:实现文件上传](http://blog.didispace.com/spring-boot-learning-21-4-3/) - [Spring Boot 2.x基础教程:多个文件的上传](http://blog.didispace.com/spring-boot-learning-21-4-4/) - [Spring Boot 2.x基础教程:文件上传的单元测试怎么写](http://blog.didispace.com/spring-boot-learning-21-4-5/) ### 任务管理 **定时任务** - [Spring Boot 2.x基础教程:使用@Scheduled实现定时任务](https://blog.didispace.com/spring-boot-learning-2-7-1) - [Spring Boot 2.x基础教程:使用Elastic Job实现定时任务](https://blog.didispace.com/spring-boot-learning-2-7-2) - [Spring Boot 2.x基础教程:使用Elastic Job的分片配置提高执行效率](https://blog.didispace.com/spring-boot-learning-2-7-3) - [Spring Boot 2.x基础教程:使用Elastic Job的namespace防止任务名冲突](https://blog.didispace.com/spring-boot-learning-2-7-4) **异步任务** - [Spring Boot 2.x基础教程:使用@Async实现异步任务](https://blog.didispace.com/spring-boot-learning-2-7-5) - [Spring Boot 2.x基础教程:配置@Async异步任务的线程池](https://blog.didispace.com/spring-boot-learning-2-7-6) - [Spring Boot 2.x基础教程:如何隔离@Async异步任务的线程池](https://blog.didispace.com/spring-boot-learning-2-7-7) - [Spring Boot 2.x基础教程:配置线程池的拒绝策略](https://blog.didispace.com/spring-boot-learning-2-7-8) ### 日志管理 - [Spring Boot 2.x基础教程:默认日志管理与Logback配置详解](https://blog.didispace.com/spring-boot-learning-2-8-1) - [Spring Boot 2.x基础教程:使用log4j2记录日志](https://blog.didispace.com/spring-boot-learning-2-8-2) - [Spring Boot 2.x基础教程:使用tinylog记录日志](https://blog.didispace.com/spring-boot-learning-2-8-3) ### 其他内容 - [Spring Boot自定义启动Banner](http://blog.didispace.com/spring-boot-banner/) - [实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件](http://blog.didispace.com/springbootmailsender/) - [使用Spring StateMachine框架实现状态机](http://blog.didispace.com/spring-statemachine/) - [Spring Boot应用的后台运行配置](http://blog.didispace.com/spring-boot-run-backend/) ## 进阶与深入 - [什么时候不要使用@Autowire](http://blog.didispace.com/when-not-use-autowire-in-spring-boot/) - [为什么加了@Transactional注解,事务没有回滚?](http://blog.didispace.com/transactional-not-rollback/) - [为什么启动时候API路径都没了?](http://blog.didispace.com/spring-boot-learning-21-2-6/) - [使用Java 8中LocalDate等时间日期类的问题解决](http://blog.didispace.com/Spring-Boot-And-Feign-Use-localdate/) - [Request header is too large 如何解决?](https://blog.didispace.com/request-header-is-too-large/) - [Spring Boot自动化配置的利弊及解决之道](http://blog.didispace.com/spring-boot-disable-autoconfig/) ## 版本资讯 ### 1.x到2.x - [Spring Boot 2.0 正式发布,升还是不升呢?](http://blog.didispace.com/spring-boot-2-release/) - [Spring Boot 2.0 新特性和发展方向](http://blog.didispace.com/Spring-Boot-2-0-%E6%96%B0%E7%89%B9%E6%80%A7%E5%92%8C%E5%8F%91%E5%B1%95%E6%96%B9%E5%90%91/) - [Spring Boot 2.0 与 Java 9](http://blog.didispace.com/Spring-Boot-2.0%E4%B8%8EJava-9/) - [Spring Boot 2.0 新特性(一):配置绑定 2.0 全解析](http://blog.didispace.com/Spring-Boot-2-0-feature-1-relaxed-binding-2/) - [Spring Boot 2.0 新特性(二):新增事件ApplicationStartedEvent](http://blog.didispace.com/Spring-Boot-2-0-feature-2-ApplicationStartedEvent/) 更多关于2.x的版本信息可查看[点击查看](http://www.springcloud.com.cn/) ## 我的公众号 ## 推荐我的书 ![Spring Boot微服务实战](https://git.oschina.net/uploads/images/2017/0416/233656_dd3bce94_437188.png) ## 特别赞助商
> 如果您也想赞助支持并出现在上表中的话,可以通过邮件联系我:`didi@didispace.com` ================================================ FILE: 2.x/README_zh.md ================================================ # Spring Boot基础教程(2.x版本) 本项目内容为[《Spring Boot基础教程》](http://blog.didispace.com/spring-boot-learning-2x/)的程序样例。 **专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程! **加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长 **Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章 **如何支持**: 1. 关注我的公众号”**程序猿DD**“ 2. 点个`Star`并`Follow`我 3. 把该仓库分享给更多的朋友 > **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
## 教程目录(2.x版本) 本教程内容持续更新连载中!**Star关注**支持一下,随时获得更新信息! ### 快速入门 - [Spring Boot 2.x基础教程:版本关系](http://blog.didispace.com/spring-cloud-alibaba-version/) - [Spring Boot 2.x基础教程:快速入门](http://blog.didispace.com/spring-boot-learning-21-1-1/) - [Spring Boot 2.x基础教程:工程结构推荐](http://blog.didispace.com/spring-boot-learning-21-1-2/) ### 配置详解 - [Spring Boot 2.x基础教程:配置文件详解](http://blog.didispace.com/spring-boot-learning-21-1-3/) - [Spring Boot 2.x基础教程:2.4版本前后的多环境配置变化](http://blog.didispace.com/spring-boot-learning-24-1-4/) - [Spring Boot 2.x基础教程:2.4版本前后的分组配置变化](http://blog.didispace.com/spring-boot-learning-24-1-5/) - [Spring Boot 2.x基础教程:配置元数据的应用 ](http://blog.didispace.com/spring-boot-learning-24-1-6/) - [Spring Boot 2.x基础教程:加密配置中的敏感信息](http://blog.didispace.com/spring-boot-learning-2-1-5/) ### API开发 - [Spring Boot 2.x基础教程:构建RESTful API与单元测试](http://blog.didispace.com/spring-boot-learning-21-2-1/) - [Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档](http://blog.didispace.com/spring-boot-learning-21-2-2/) - [Spring Boot 2.x基础教程:JSR-303实现请求参数校验](http://blog.didispace.com/spring-boot-learning-21-2-3/) - [Spring Boot 2.x基础教程:Swagger接口分类与各元素排序问题详解](http://blog.didispace.com/spring-boot-learning-21-2-4/) - [Spring Boot 2.x基础教程:Swagger静态文档的生成](http://blog.didispace.com/spring-boot-learning-21-2-5/) - [Spring Boot 2.x基础教程:找回启动日志中的请求路径列表](http://blog.didispace.com/spring-boot-learning-21-2-6/) - [Spring Boot 2.x基础教程:使用SpringFox 3生成Swagger文档](http://blog.didispace.com/spring-boot-learning-21-2-7/) - [Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应](http://blog.didispace.com/spring-boot-learning-21-2-8/) ### 数据访问 **关系型数据库** - [Spring Boot 2.x基础教程:使用JdbcTemplate访问MySQL数据库](http://blog.didispace.com/spring-boot-learning-21-3-1/) - [Spring Boot 2.x基础教程:默认数据源Hikari的配置详解](http://blog.didispace.com/spring-boot-learning-21-3-2/) - [Spring Boot 2.x基础教程:使用国产数据库连接池Druid](http://blog.didispace.com/spring-boot-learning-21-3-3/) - [Spring Boot 2.x基础教程:使用Spring Data JPA访问MySQL](http://blog.didispace.com/spring-boot-learning-21-3-4/) - [Spring Boot 2.x基础教程:使用MyBatis访问MySQL](http://blog.didispace.com/spring-boot-learning-21-3-5/) - [Spring Boot 2.x基础教程:使用MyBatis的XML配置方式](http://blog.didispace.com/spring-boot-learning-21-3-6/) - [Spring Boot 2.x基础教程:JdbcTemplate的多数据源配置](http://blog.didispace.com/spring-boot-learning-21-3-7/) - [Spring Boot 2.x基础教程:Spring Data JPA的多数据源配置](http://blog.didispace.com/spring-boot-learning-21-3-8/) - [Spring Boot 2.x基础教程:MyBatis的多数据源配置](http://blog.didispace.com/spring-boot-learning-21-3-9/) - [Spring Boot 2.x基础教程:事务管理入门](http://blog.didispace.com/spring-boot-learning-21-3-10/) - [Spring Boot 2.x基础教程:使用Flyway管理数据库版本](http://blog.didispace.com/spring-boot-learning-24-3-11/) - [Spring Boot 2.x基础教程:使用JTA实现多数据源的事务管理](http://blog.didispace.com/spring-boot-learning-24-3-12/) - [Spring Boot 2.x基础教程:2.5版本后数据脚本初始化的变动](http://blog.didispace.com/spring-boot-learning-25-3-13/) **加速利器:各种缓存的使用** - [Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解](http://blog.didispace.com/spring-boot-learning-21-5-1/) - [Spring Boot 2.x基础教程:EhCache缓存的使用](http://blog.didispace.com/spring-boot-learning-21-5-2/) - [Spring Boot 2.x基础教程:使用EhCache缓存集群](http://blog.didispace.com/spring-boot-learning-21-5-3/) - [Spring Boot 2.x基础教程:使用集中式缓存Redis](http://blog.didispace.com/spring-boot-learning-21-5-4/) - [Spring Boot 2.x基础教程:使用Redis的发布订阅功能](http://blog.didispace.com/spring-boot-learning-25-5-5/) **其他常见存储的使用** - [Spring Boot 2.x基础教程:使用MongoDB](http://blog.didispace.com/spring-boot-learning-24-6-1/) - [Spring Boot 2.x基础教程:使用LDAP来管理用户与组织数据](http://blog.didispace.com/spring-boot-learning-24-6-2/) - [Spring Boot 2.x基础教程:使用时序数据库InfluxDB](http://blog.didispace.com/spring-boot-learning-2-6-3/) - [Spring Boot 2.x基础教程:使用PostgreSQL](http://blog.didispace.com/spring-boot-learning-2-6-4/) ### Web开发 - [Spring Boot 2.x基础教程:使用 Thymeleaf开发Web页面](http://blog.didispace.com/spring-boot-learning-21-4-1/) - [Spring Boot 2.x基础教程:使用 ECharts 绘制各种华丽的数据图表](http://blog.didispace.com/spring-boot-learning-21-4-2/) - [Spring Boot 2.x基础教程:实现文件上传](http://blog.didispace.com/spring-boot-learning-21-4-3/) - [Spring Boot 2.x基础教程:多个文件的上传](http://blog.didispace.com/spring-boot-learning-21-4-4/) - [Spring Boot 2.x基础教程:文件上传的单元测试怎么写](http://blog.didispace.com/spring-boot-learning-21-4-5/) ### 任务管理 **定时任务** - [Spring Boot 2.x基础教程:使用@Scheduled实现定时任务](https://blog.didispace.com/spring-boot-learning-2-7-1) - [Spring Boot 2.x基础教程:使用Elastic Job实现定时任务](https://blog.didispace.com/spring-boot-learning-2-7-2) - [Spring Boot 2.x基础教程:使用Elastic Job的分片配置提高执行效率](https://blog.didispace.com/spring-boot-learning-2-7-3) - [Spring Boot 2.x基础教程:使用Elastic Job的namespace防止任务名冲突](https://blog.didispace.com/spring-boot-learning-2-7-4) **异步任务** - [Spring Boot 2.x基础教程:使用@Async实现异步任务](https://blog.didispace.com/spring-boot-learning-2-7-5) - [Spring Boot 2.x基础教程:配置@Async异步任务的线程池](https://blog.didispace.com/spring-boot-learning-2-7-6) - [Spring Boot 2.x基础教程:如何隔离@Async异步任务的线程池](https://blog.didispace.com/spring-boot-learning-2-7-7) - [Spring Boot 2.x基础教程:配置线程池的拒绝策略](https://blog.didispace.com/spring-boot-learning-2-7-8) ### 日志管理 - [Spring Boot 2.x基础教程:默认日志管理与Logback配置详解](https://blog.didispace.com/spring-boot-learning-2-8-1) - [Spring Boot 2.x基础教程:使用log4j2记录日志](https://blog.didispace.com/spring-boot-learning-2-8-2) - [Spring Boot 2.x基础教程:使用tinylog记录日志](https://blog.didispace.com/spring-boot-learning-2-8-3) ### 其他内容 - [Spring Boot自定义启动Banner](http://blog.didispace.com/spring-boot-banner/) - [实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件](http://blog.didispace.com/springbootmailsender/) - [使用Spring StateMachine框架实现状态机](http://blog.didispace.com/spring-statemachine/) - [Spring Boot应用的后台运行配置](http://blog.didispace.com/spring-boot-run-backend/) ## 进阶与深入 - [什么时候不要使用@Autowire](http://blog.didispace.com/when-not-use-autowire-in-spring-boot/) - [为什么加了@Transactional注解,事务没有回滚?](http://blog.didispace.com/transactional-not-rollback/) - [为什么启动时候API路径都没了?](http://blog.didispace.com/spring-boot-learning-21-2-6/) - [使用Java 8中LocalDate等时间日期类的问题解决](http://blog.didispace.com/Spring-Boot-And-Feign-Use-localdate/) - [Request header is too large 如何解决?](https://blog.didispace.com/request-header-is-too-large/) - [Spring Boot自动化配置的利弊及解决之道](http://blog.didispace.com/spring-boot-disable-autoconfig/) ## 版本资讯 ### 1.x到2.x - [Spring Boot 2.0 正式发布,升还是不升呢?](http://blog.didispace.com/spring-boot-2-release/) - [Spring Boot 2.0 新特性和发展方向](http://blog.didispace.com/Spring-Boot-2-0-%E6%96%B0%E7%89%B9%E6%80%A7%E5%92%8C%E5%8F%91%E5%B1%95%E6%96%B9%E5%90%91/) - [Spring Boot 2.0 与 Java 9](http://blog.didispace.com/Spring-Boot-2.0%E4%B8%8EJava-9/) - [Spring Boot 2.0 新特性(一):配置绑定 2.0 全解析](http://blog.didispace.com/Spring-Boot-2-0-feature-1-relaxed-binding-2/) - [Spring Boot 2.0 新特性(二):新增事件ApplicationStartedEvent](http://blog.didispace.com/Spring-Boot-2-0-feature-2-ApplicationStartedEvent/) ### 2.x版本信息 - [Spring Boot 2.2 正式发布,大幅性能提升 + Java 13 支持](http://blog.didispace.com/spring-boot-2-2-release/) - [Spring Boot 2.3.0 发布](/spring-boot-2-3-0-release/) - [Spring Boot 2.3.0 放弃 Maven 转投 Gradle](/spring-boot-gradle/) - [Spring Boot 2.3.2 发布,解决 Too many open files 导致的应用宕机问题](http://blog.didispace.com/spring-boot-2-3-2-release/) - [Spring Boot 2.4.0 正式发布!全新的配置处理机制,拥抱云原生!](http://blog.didispace.com/spring-boot-2-4-0-ga/) - [Spring Boot 2.4.1 发布,修正大量2.4全新配置机制的Bug](http://blog.didispace.com/spring-boot-2-4-1-release/) - [Spring Boot 2.5.0 发布:支持Java16、Gradle 7、Datasource初始化调整](https://blog.didispace.com/spring-boot-2-5-0-release/) - [Spring Boot 2.5.1 发布](https://blog.didispace.com/spring-boot-2-5-1-release/) ## 推荐内容 - [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容 - [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活 - [Spring Boot基础教程](http://blog.didispace.com/Spring-Boot%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/):全网Star最多的免费Spring Boot基础教程 - [Spring Cloud基础教程](http://blog.didispace.com/Spring-Cloud%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/):全网最早最全的免费Spring Cloud基础教程 ## 我的公众号 ## 推荐我的书 ![Spring Boot微服务实战](https://git.oschina.net/uploads/images/2017/0416/233656_dd3bce94_437188.png) ## 特别赞助商
> 如果您也想赞助支持并出现在上表中的话,可以通过邮件联系我:`didi@didispace.com` ================================================ FILE: 2.x/chapter1-1/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter1-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter1-1 0.0.1-SNAPSHOT chapter1-1 快速入门 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter1-1/src/main/java/com/didispace/chapter11/Chapter11Application.java ================================================ package com.didispace.chapter11; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter11Application { public static void main(String[] args) { SpringApplication.run(Chapter11Application.class, args); } } ================================================ FILE: 2.x/chapter1-1/src/main/java/com/didispace/chapter11/HelloController.java ================================================ package com.didispace.chapter11; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } } ================================================ FILE: 2.x/chapter1-1/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter1-1/src/test/java/com/didispace/chapter11/Chapter11ApplicationTests.java ================================================ package com.didispace.chapter11; import org.junit.Before; import org.junit.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest public class Chapter11ApplicationTests { private MockMvc mvc; @Before public void setUp() { mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World"))); } } ================================================ FILE: 2.x/chapter1-2/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter1-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter1-2 0.0.1-SNAPSHOT chapter1-2 2.4版本前后的多环境配置与配置激活 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter1-2/src/main/java/com/didispace/chapter12/Chapter12Application.java ================================================ package com.didispace.chapter12; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Chapter12Application { public static void main(String[] args) { SpringApplication.run(Chapter12Application.class, args); } @RestController static class HelloController { @Value("${name:}") private String name; @RequestMapping("/") public String index() { return name; } } } ================================================ FILE: 2.x/chapter1-2/src/main/resources/application.yaml ================================================ # 默认激活dev配置 spring: profiles: active: "dev" --- spring: config: activate: on-profile: "dev" name: dev.didispace.com --- spring: config: activate: on-profile: "test" name: test.didispace.com --- spring: config: activate: on-profile: "prod" name: prod.didispace.com ================================================ FILE: 2.x/chapter1-3/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter1-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter1-3 0.0.1-SNAPSHOT chapter1-3 2.4版本前后的配置分组配置 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter1-3/src/main/java/com/didispace/chapter13/Chapter13Application.java ================================================ package com.didispace.chapter13; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Chapter13Application { public static void main(String[] args) { SpringApplication.run(Chapter13Application.class, args); } @Slf4j @RestController static class HelloController { @Value("${db:}") private String db; @Value("${mq:}") private String mq; @RequestMapping("/") public String index() { log.info("db:" + db); log.info("mq:" + mq); return ""; } } } ================================================ FILE: 2.x/chapter1-3/src/main/resources/application.yaml ================================================ # 2.4之前的配置 #spring: # profiles: # active: "dev" # #--- #spring.profiles: "dev" #spring.profiles.include: "dev-db,dev-mq" # #--- #spring.profiles: "dev-db" # #db: dev-db.didispace.com # #--- #spring.profiles: "dev-mq" # #mq: dev-mq.didispace.com # #--- #2.4之后的配置 # 默认激活dev配置 spring: profiles: active: "dev" group: "dev": "dev-db,dev-mq" "prod": "prod-db,prod-mq" --- spring: config: activate: on-profile: "dev-db" db: dev-db.didispace.com --- spring: config: activate: on-profile: "dev-mq" mq: dev-mq.didispace.com --- spring: config: activate: on-profile: "prod-db" db: prod-db.didispace.com --- spring: config: activate: on-profile: "prod-mq" mq: prod-mq.didispace.com ================================================ FILE: 2.x/chapter1-4/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter1-4/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter1-4 0.0.1-SNAPSHOT chapter1-4 配置元数据的应用 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-configuration-processor org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter1-4/src/main/java/com/didispace/chapter14/Chapter14Application.java ================================================ package com.didispace.chapter14; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter14Application { public static void main(String[] args) { SpringApplication.run(Chapter14Application.class, args); } } ================================================ FILE: 2.x/chapter1-4/src/main/java/com/didispace/chapter14/DidiProperties.java ================================================ package com.didispace.chapter14; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "com.didispace") public class DidiProperties { /** * 这是一个测试配置 */ private String from; } ================================================ FILE: 2.x/chapter1-4/src/main/java/com/didispace/chapter14/HelloController.java ================================================ package com.didispace.chapter14; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String index() { return "Hello World"; } } ================================================ FILE: 2.x/chapter1-4/src/main/resources/application.properties ================================================ com.didispace.from=didi ================================================ FILE: 2.x/chapter1-5/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter1-5/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter1-5 0.0.1-SNAPSHOT 加密配置中的敏感信息 1.8 org.springframework.boot spring-boot-starter-web com.github.ulisesbocchio jasypt-spring-boot-starter 3.0.3 org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin com.github.ulisesbocchio jasypt-maven-plugin 3.0.3 ================================================ FILE: 2.x/chapter1-5/src/main/java/com/didispace/chapter15/Chapter15Application.java ================================================ package com.didispace.chapter15; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter15Application { public static void main(String[] args) { SpringApplication.run(Chapter15Application.class, args); } } ================================================ FILE: 2.x/chapter1-5/src/main/resources/application.properties ================================================ datasource.password=ENC(/AL9nJENCYCh9Pfzdf2xLPsqOZ6HwNgQ3AnMybFAMeOM5GphZlOK6PxzozwtCm+Q) jasypt.encryptor.password=didispace # mvn jasypt:encrypt -Djasypt.encryptor.password=didispace # mvn jasypt:decrypt -Djasypt.encryptor.password=didispace #jasypt.encryptor.property.prefix=ENC( #jasypt.encryptor.property.suffix=) ================================================ FILE: 2.x/chapter1-5/src/test/java/com/didispace/chapter15/PropertiesTest.java ================================================ package com.didispace.chapter15; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; @Slf4j @SpringBootTest public class PropertiesTest { @Value("${datasource.password:}") private String password; @Test public void test() { log.info("datasource.password : {}", password); } } ================================================ FILE: 2.x/chapter2-1/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter2-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter2-1 0.0.1-SNAPSHOT chapter2-1 构建RESTful API与单元测试 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter2-1/src/main/java/com/didispace/chapter21/Chapter21Application.java ================================================ package com.didispace.chapter21; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter21Application { public static void main(String[] args) { SpringApplication.run(Chapter21Application.class, args); } } ================================================ FILE: 2.x/chapter2-1/src/main/java/com/didispace/chapter21/User.java ================================================ package com.didispace.chapter21; import lombok.Data; @Data public class User { private Long id; private String name; private Integer age; } ================================================ FILE: 2.x/chapter2-1/src/main/java/com/didispace/chapter21/UserController.java ================================================ package com.didispace.chapter21; import org.springframework.web.bind.annotation.*; import java.util.*; @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下 public class UserController { // 创建线程安全的Map,模拟users信息的存储 static Map users = Collections.synchronizedMap(new HashMap()); /** * 处理"/users/"的GET请求,用来获取用户列表 * * @return */ @GetMapping("/") public List getUserList() { // 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递 List r = new ArrayList(users.values()); return r; } /** * 处理"/users/"的POST请求,用来创建User * * @param user * @return */ @PostMapping("/") public String postUser(@RequestBody User user) { // @RequestBody注解用来绑定通过http请求中application/json类型上传的数据 users.put(user.getId(), user); return "success"; } /** * 处理"/users/{id}"的GET请求,用来获取url中id值的User信息 * * @param id * @return */ @GetMapping("/{id}") public User getUser(@PathVariable Long id) { // url中的id可通过@PathVariable绑定到函数的参数中 return users.get(id); } /** * 处理"/users/{id}"的PUT请求,用来更新User信息 * * @param id * @param user * @return */ @PutMapping("/{id}") public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } /** * 处理"/users/{id}"的DELETE请求,用来删除User * * @param id * @return */ @DeleteMapping("/{id}") public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 2.x/chapter2-1/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter2-1/src/test/java/com/didispace/chapter21/Chapter21ApplicationTests.java ================================================ package com.didispace.chapter21; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest public class Chapter21ApplicationTests { private MockMvc mvc; @Before public void setUp() { mvc = MockMvcBuilders.standaloneSetup(new UserController()).build(); } @Test public void testUserController() throws Exception { // 测试UserController RequestBuilder request; // 1、get查一下user列表,应该为空 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[]"))); // 2、post提交一个user request = post("/users/") .contentType(MediaType.APPLICATION_JSON) .content("{\"id\":1,\"name\":\"测试大师\",\"age\":20}"); mvc.perform(request) .andExpect(content().string(equalTo("success"))); // 3、get获取user列表,应该有刚才插入的数据 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[{\"id\":1,\"name\":\"测试大师\",\"age\":20}]"))); // 4、put修改id为1的user request = put("/users/1") .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"测试终极大师\",\"age\":30}"); mvc.perform(request) .andExpect(content().string(equalTo("success"))); // 5、get一个id为1的user request = get("/users/1"); mvc.perform(request) .andExpect(content().string(equalTo("{\"id\":1,\"name\":\"测试终极大师\",\"age\":30}"))); // 6、del删除id为1的user request = delete("/users/1"); mvc.perform(request) .andExpect(content().string(equalTo("success"))); // 7、get查一下user列表,应该为空 request = get("/users/"); mvc.perform(request) .andExpect(status().isOk()) .andExpect(content().string(equalTo("[]"))); } } ================================================ FILE: 2.x/chapter2-2/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter2-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter2-2 0.0.1-SNAPSHOT chapter2-2 使用Swagger2构建强大的API文档 1.8 org.springframework.boot spring-boot-starter-web com.spring4all swagger-spring-boot-starter 1.9.0.RELEASE org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter2-2/src/main/java/com/didispace/chapter22/Chapter22Application.java ================================================ package com.didispace.chapter22; import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableSwagger2Doc @SpringBootApplication public class Chapter22Application { public static void main(String[] args) { SpringApplication.run(Chapter22Application.class, args); } } ================================================ FILE: 2.x/chapter2-2/src/main/java/com/didispace/chapter22/User.java ================================================ package com.didispace.chapter22; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(description="用户实体") public class User { @ApiModelProperty("用户编号") private Long id; @ApiModelProperty("用户姓名") private String name; @ApiModelProperty("用户年龄") private Integer age; } ================================================ FILE: 2.x/chapter2-2/src/main/java/com/didispace/chapter22/UserController.java ================================================ package com.didispace.chapter22; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import java.util.*; @Api(tags = "用户管理") @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下 public class UserController { // 创建线程安全的Map,模拟users信息的存储 static Map users = Collections.synchronizedMap(new HashMap<>()); @GetMapping("/") @ApiOperation(value = "获取用户列表") public List getUserList() { List r = new ArrayList<>(users.values()); return r; } @PostMapping("/") @ApiOperation(value = "创建用户", notes = "根据User对象创建用户") public String postUser(@RequestBody User user) { users.put(user.getId(), user); return "success"; } @GetMapping("/{id}") @ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息") public User getUser(@PathVariable Long id) { return users.get(id); } @PutMapping("/{id}") @ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "用户编号", required = true, example = "1") @ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @DeleteMapping("/{id}") @ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象") public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 2.x/chapter2-2/src/main/resources/application.properties ================================================ swagger.title=spring-boot-starter-swagger swagger.description=Starter for swagger 2.x swagger.version=1.9.0.RELEASE swagger.license=Apache License, Version 2.0 swagger.licenseUrl=https://www.apache.org/licenses/LICENSE-2.0.html swagger.termsOfServiceUrl=https://github.com/dyc87112/spring-boot-starter-swagger swagger.contact.name=didi swagger.contact.url=http://blog.didispace.com swagger.contact.email=dyc87112@qq.com swagger.base-package=com.didispace swagger.base-path=/** ================================================ FILE: 2.x/chapter2-3/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter2-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter2-3 0.0.1-SNAPSHOT chapter2-3 使用JSR-303实现请求参数校验 1.8 org.springframework.boot spring-boot-starter-web com.spring4all swagger-spring-boot-starter 1.9.0.RELEASE org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter2-3/src/main/java/com/didispace/chapter23/Chapter23Application.java ================================================ package com.didispace.chapter23; import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableSwagger2Doc @SpringBootApplication public class Chapter23Application { public static void main(String[] args) { SpringApplication.run(Chapter23Application.class, args); } } ================================================ FILE: 2.x/chapter2-3/src/main/java/com/didispace/chapter23/User.java ================================================ package com.didispace.chapter23; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.*; @Data @ApiModel(description = "用户实体") public class User { @ApiModelProperty("用户编号") private Long id; @NotNull @Size(min = 2, max = 5) @ApiModelProperty("用户姓名") private String name; @NotNull @Max(100) @Min(10) @ApiModelProperty("用户年龄") private Integer age; @NotNull @Email @ApiModelProperty("用户邮箱") private String email; } ================================================ FILE: 2.x/chapter2-3/src/main/java/com/didispace/chapter23/UserController.java ================================================ package com.didispace.chapter23; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.*; @Api(tags = "用户管理") @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下 public class UserController { // 创建线程安全的Map,模拟users信息的存储 static Map users = Collections.synchronizedMap(new HashMap<>()); @GetMapping("/") @ApiOperation(value = "获取用户列表") public List getUserList() { List r = new ArrayList<>(users.values()); return r; } @PostMapping("/") @ApiOperation(value = "创建用户", notes = "根据User对象创建用户") public String postUser(@Valid @RequestBody User user) { users.put(user.getId(), user); return "success"; } @GetMapping("/{id}") @ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息") public User getUser(@PathVariable Long id) { return users.get(id); } @PutMapping("/{id}") @ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "用户编号", required = true, example = "1") @ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @DeleteMapping("/{id}") @ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象") public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 2.x/chapter2-3/src/main/resources/application.properties ================================================ swagger.title=spring-boot-starter-swagger swagger.description=Starter for swagger 2.x swagger.version=1.9.0.RELEASE swagger.license=Apache License, Version 2.0 swagger.licenseUrl=https://www.apache.org/licenses/LICENSE-2.0.html swagger.termsOfServiceUrl=https://github.com/dyc87112/spring-boot-starter-swagger swagger.contact.name=didi swagger.contact.url=http://blog.didispace.com swagger.contact.email=dyc87112@qq.com swagger.base-package=com.didispace swagger.base-path=/** ================================================ FILE: 2.x/chapter2-4/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter2-4/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter2-4 0.0.1-SNAPSHOT chapter2-4 Swagger接口分类与各元素排序问题详解 1.8 org.springframework.boot spring-boot-starter-web com.spring4all swagger-spring-boot-starter 1.9.0.RELEASE org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter2-4/src/main/java/com/didispace/chapter24/Chapter24Application.java ================================================ package com.didispace.chapter24; import com.spring4all.swagger.EnableSwagger2Doc; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Tag; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; @EnableSwagger2Doc @SpringBootApplication public class Chapter24Application { public static void main(String[] args) { SpringApplication.run(Chapter24Application.class, args); } @Api(tags = {"1-教师管理","3-教学管理"}) @RestController @RequestMapping(value = "/teacher") static class TeacherController { @ApiOperation(value = "xxx") @GetMapping("/xxx") public String xxx() { return "xxx"; } } @Api(tags = {"2-学生管理"}) @RestController @RequestMapping(value = "/student") static class StudentController { @ApiOperation(value = "获取学生清单", tags = "3-教学管理") @GetMapping("/list") public String bbb() { return "bbb"; } @ApiOperation("获取教某个学生的老师清单") @GetMapping("/his-teachers") public String ccc() { return "ccc"; } @ApiOperation("创建一个学生") @PostMapping("/aaa") public String aaa() { return "aaa"; } } } ================================================ FILE: 2.x/chapter2-4/src/main/java/com/didispace/chapter24/User.java ================================================ package com.didispace.chapter24; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.*; @Data @ApiModel(description = "用户实体") public class User { @ApiModelProperty(value = "用户编号", position = 1) private Long id; @NotNull @Size(min = 2, max = 5) @ApiModelProperty(value = "用户姓名", position = 2) private String name; @NotNull @Max(100) @Min(10) @ApiModelProperty(value = "用户年龄", position = 3) private Integer age; @NotNull @Email @ApiModelProperty(value = "用户邮箱", position = 4) private String email; } ================================================ FILE: 2.x/chapter2-4/src/main/java/com/didispace/chapter24/UserController.java ================================================ package com.didispace.chapter24; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.*; @Api(tags = "用户管理") @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下 public class UserController { // 创建线程安全的Map,模拟users信息的存储 static Map users = Collections.synchronizedMap(new HashMap<>()); @GetMapping("/") @ApiOperation(value = "获取用户列表") public List getUserList() { List r = new ArrayList<>(users.values()); return r; } @PostMapping("/") @ApiOperation(value = "创建用户", notes = "根据User对象创建用户") public String postUser(@Valid @RequestBody User user) { users.put(user.getId(), user); return "success"; } @GetMapping("/{id}") @ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息") public User getUser(@PathVariable Long id) { return users.get(id); } @PutMapping("/{id}") @ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "用户编号", required = true, example = "1") @ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @DeleteMapping("/{id}") @ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象") public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 2.x/chapter2-4/src/main/resources/application.properties ================================================ swagger.title=spring-boot-starter-swagger swagger.description=Starter for swagger 2.x swagger.version=1.9.0.RELEASE swagger.license=Apache License, Version 2.0 swagger.licenseUrl=https://www.apache.org/licenses/LICENSE-2.0.html swagger.termsOfServiceUrl=https://github.com/dyc87112/spring-boot-starter-swagger swagger.contact.name=didi swagger.contact.url=http://blog.didispace.com swagger.contact.email=dyc87112@qq.com swagger.base-package=com.didispace swagger.base-path=/** swagger.ui-config.tags-sorter=alpha swagger.ui-config.operations-sorter=alpha ================================================ FILE: 2.x/chapter2-5/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter2-5/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter2-5 0.0.1-SNAPSHOT chapter2-5 Swagger静态文档的生成 1.8 org.springframework.boot spring-boot-starter-web com.spring4all swagger-spring-boot-starter 1.9.0.RELEASE org.projectlombok lombok org.springframework.boot spring-boot-starter-test test io.github.swagger2markup swagger2markup 1.3.3 test org.springframework.boot spring-boot-maven-plugin io.github.swagger2markup swagger2markup-maven-plugin 1.3.3 http://localhost:8080/v2/api-docs src/docs/asciidoc/generated-by-plugin ASCIIDOC org.asciidoctor asciidoctor-maven-plugin 1.5.6 src/docs/asciidoc/generated src/docs/asciidoc/html html coderay left false jcenter-releases jcenter http://jcenter.bintray.com ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated/definitions.adoc ================================================ [[_definitions]] == Definitions [[_user]] === User 用户实体 [options="header", cols=".^3a,.^11a,.^4a"] |=== |Name|Description|Schema |**age** + __optional__|用户年龄|integer (int32) |**id** + __optional__|用户编号|integer (int64) |**name** + __optional__|用户姓名|string |=== ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated/overview.adoc ================================================ = spring-boot-starter-swagger [[_overview]] == Overview Starter for swagger 2.x === Version information [%hardbreaks] __Version__ : 1.9.0.RELEASE === Contact information [%hardbreaks] __Contact__ : didi __Contact Email__ : dyc87112@qq.com === License information [%hardbreaks] __License__ : Apache License, Version 2.0 __License URL__ : https://www.apache.org/licenses/LICENSE-2.0.html __Terms of service__ : https://github.com/dyc87112/spring-boot-starter-swagger === URI scheme [%hardbreaks] __Host__ : localhost:8080 __BasePath__ : / === Tags * 用户管理 : User Controller ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated/paths.adoc ================================================ [[_paths]] == Paths [[_postuserusingpost]] === 创建用户 .... POST /users/ .... ==== Description 根据User对象创建用户 ==== Parameters [options="header", cols=".^2a,.^3a,.^9a,.^4a"] |=== |Type|Name|Description|Schema |**Body**|**user** + __required__|user|<<_user,User>> |=== ==== Responses [options="header", cols=".^2a,.^14a,.^4a"] |=== |HTTP Code|Description|Schema |**200**|OK|string |**201**|Created|No Content |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Consumes * `application/json` ==== Produces * `\*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3a,.^4a,.^13a"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_getuserlistusingget]] === 获取用户列表 .... GET /users/ .... ==== Responses [options="header", cols=".^2a,.^14a,.^4a"] |=== |HTTP Code|Description|Schema |**200**|OK|< <<_user,User>> > array |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Produces * `\*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3a,.^4a,.^13a"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_getuserusingget]] === 获取用户详细信息 .... GET /users/{id} .... ==== Description 根据url的id来获取用户详细信息 ==== Parameters [options="header", cols=".^2a,.^3a,.^9a,.^4a"] |=== |Type|Name|Description|Schema |**Path**|**id** + __required__|id|integer (int64) |=== ==== Responses [options="header", cols=".^2a,.^14a,.^4a"] |=== |HTTP Code|Description|Schema |**200**|OK|<<_user,User>> |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Produces * `\*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3a,.^4a,.^13a"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_putuserusingput]] === 更新用户详细信息 .... PUT /users/{id} .... ==== Description 根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息 ==== Parameters [options="header", cols=".^2a,.^3a,.^9a,.^4a"] |=== |Type|Name|Description|Schema |**Path**|**id** + __required__|用户编号|integer (int64) |**Body**|**user** + __required__|user|<<_user,User>> |=== ==== Responses [options="header", cols=".^2a,.^14a,.^4a"] |=== |HTTP Code|Description|Schema |**200**|OK|string |**201**|Created|No Content |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Consumes * `application/json` ==== Produces * `\*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3a,.^4a,.^13a"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_deleteuserusingdelete]] === 删除用户 .... DELETE /users/{id} .... ==== Description 根据url的id来指定删除对象 ==== Parameters [options="header", cols=".^2a,.^3a,.^9a,.^4a"] |=== |Type|Name|Description|Schema |**Path**|**id** + __required__|id|integer (int64) |=== ==== Responses [options="header", cols=".^2a,.^14a,.^4a"] |=== |HTTP Code|Description|Schema |**200**|OK|string |**204**|No Content|No Content |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |=== ==== Produces * `\*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3a,.^4a,.^13a"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated/security.adoc ================================================ [[_securityscheme]] == Security [[_authorization]] === Authorization [%hardbreaks] __Type__ : apiKey __Name__ : TOKEN __In__ : HEADER ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/definitions.adoc ================================================ [[_definitions]] == Definitions [[_user]] === User 用户实体 [options="header", cols=".^3,.^11,.^4"] |=== |Name|Description|Schema |**age** + __optional__|用户年龄|integer (int32) |**id** + __optional__|用户编号|integer (int64) |**name** + __optional__|用户姓名|string |=== ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/overview.adoc ================================================ = spring-boot-starter-swagger [[_overview]] == Overview Starter for swagger 2.x === Version information [%hardbreaks] __Version__ : 1.9.0.RELEASE === Contact information [%hardbreaks] __Contact__ : didi __Contact Email__ : dyc87112@qq.com === License information [%hardbreaks] __License__ : Apache License, Version 2.0 __License URL__ : https://www.apache.org/licenses/LICENSE-2.0.html __Terms of service__ : https://github.com/dyc87112/spring-boot-starter-swagger === URI scheme [%hardbreaks] __Host__ : localhost:8080 __BasePath__ : / === Tags * 用户管理 : User Controller ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/paths.adoc ================================================ [[_paths]] == Paths [[_postuserusingpost]] === 创建用户 .... POST /users/ .... ==== Description 根据User对象创建用户 ==== Parameters [options="header", cols=".^2,.^3,.^9,.^4"] |=== |Type|Name|Description|Schema |**Body**|**user** + __required__|user|<<_user,User>> |=== ==== Responses [options="header", cols=".^2,.^14,.^4"] |=== |HTTP Code|Description|Schema |**200**|OK|string |**201**|Created|No Content |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Consumes * `application/json` ==== Produces * `*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3,.^4,.^13"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_getuserlistusingget]] === 获取用户列表 .... GET /users/ .... ==== Responses [options="header", cols=".^2,.^14,.^4"] |=== |HTTP Code|Description|Schema |**200**|OK|< <<_user,User>> > array |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Produces * `*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3,.^4,.^13"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_getuserusingget]] === 获取用户详细信息 .... GET /users/{id} .... ==== Description 根据url的id来获取用户详细信息 ==== Parameters [options="header", cols=".^2,.^3,.^9,.^4"] |=== |Type|Name|Description|Schema |**Path**|**id** + __required__|id|integer (int64) |=== ==== Responses [options="header", cols=".^2,.^14,.^4"] |=== |HTTP Code|Description|Schema |**200**|OK|<<_user,User>> |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Produces * `*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3,.^4,.^13"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_putuserusingput]] === 更新用户详细信息 .... PUT /users/{id} .... ==== Description 根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息 ==== Parameters [options="header", cols=".^2,.^3,.^9,.^4"] |=== |Type|Name|Description|Schema |**Path**|**id** + __required__|用户编号|integer (int64) |**Body**|**user** + __required__|user|<<_user,User>> |=== ==== Responses [options="header", cols=".^2,.^14,.^4"] |=== |HTTP Code|Description|Schema |**200**|OK|string |**201**|Created|No Content |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |**404**|Not Found|No Content |=== ==== Consumes * `application/json` ==== Produces * `*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3,.^4,.^13"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== [[_deleteuserusingdelete]] === 删除用户 .... DELETE /users/{id} .... ==== Description 根据url的id来指定删除对象 ==== Parameters [options="header", cols=".^2,.^3,.^9,.^4"] |=== |Type|Name|Description|Schema |**Path**|**id** + __required__|id|integer (int64) |=== ==== Responses [options="header", cols=".^2,.^14,.^4"] |=== |HTTP Code|Description|Schema |**200**|OK|string |**204**|No Content|No Content |**401**|Unauthorized|No Content |**403**|Forbidden|No Content |=== ==== Produces * `*/*` ==== Tags * 用户管理 ==== Security [options="header", cols=".^3,.^4,.^13"] |=== |Type|Name|Scopes |**apiKey**|**<<_authorization,Authorization>>**|global |=== ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/security.adoc ================================================ [[_securityscheme]] == Security [[_authorization]] === Authorization [%hardbreaks] __Type__ : apiKey __Name__ : TOKEN __In__ : HEADER ================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/html/definitions.html ================================================ Definitions

Definitions

User

用户实体

Name Description Schema

age
optional

用户年龄

integer (int32)

id
optional

用户编号

integer (int64)

name
optional

用户姓名

string

================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/html/overview.html ================================================ spring-boot-starter-swagger

Overview

Starter for swagger 2.x

Version information

Version : 1.9.0.RELEASE

Contact information

Contact : didi
Contact Email : dyc87112@qq.com

License information

License : Apache License, Version 2.0
License URL : https://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : https://github.com/dyc87112/spring-boot-starter-swagger

URI scheme

Host : localhost:8080
BasePath : /

Tags

  • 用户管理 : User Controller

================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/html/paths.html ================================================ Paths

Paths

创建用户

POST /users/

Description

根据User对象创建用户

Parameters

Type Name Description Schema

Body

user
required

user

Responses

HTTP Code Description Schema

200

OK

string

201

Created

No Content

401

Unauthorized

No Content

403

Forbidden

No Content

404

Not Found

No Content

Consumes

  • application/json

Produces

  • */*

Tags

  • 用户管理

Security

Type Name Scopes

apiKey

global

获取用户列表

GET /users/

Responses

HTTP Code Description Schema

200

OK

< User > array

401

Unauthorized

No Content

403

Forbidden

No Content

404

Not Found

No Content

Produces

  • */*

Tags

  • 用户管理

Security

Type Name Scopes

apiKey

global

获取用户详细信息

GET /users/{id}

Description

根据url的id来获取用户详细信息

Parameters

Type Name Description Schema

Path

id
required

id

integer (int64)

Responses

HTTP Code Description Schema

200

OK

401

Unauthorized

No Content

403

Forbidden

No Content

404

Not Found

No Content

Produces

  • */*

Tags

  • 用户管理

Security

Type Name Scopes

apiKey

global

更新用户详细信息

PUT /users/{id}

Description

根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息

Parameters

Type Name Description Schema

Path

id
required

用户编号

integer (int64)

Body

user
required

user

Responses

HTTP Code Description Schema

200

OK

string

201

Created

No Content

401

Unauthorized

No Content

403

Forbidden

No Content

404

Not Found

No Content

Consumes

  • application/json

Produces

  • */*

Tags

  • 用户管理

Security

Type Name Scopes

apiKey

global

删除用户

DELETE /users/{id}

Description

根据url的id来指定删除对象

Parameters

Type Name Description Schema

Path

id
required

id

integer (int64)

Responses

HTTP Code Description Schema

200

OK

string

204

No Content

No Content

401

Unauthorized

No Content

403

Forbidden

No Content

Produces

  • */*

Tags

  • 用户管理

Security

Type Name Scopes

apiKey

global

================================================ FILE: 2.x/chapter2-5/src/docs/asciidoc/html/security.html ================================================ Security

Security

Authorization

Type : apiKey
Name : TOKEN
In : HEADER

================================================ FILE: 2.x/chapter2-5/src/docs/confluence/generated/definitions.txt ================================================ h2. Definitions {anchor:definitions} h3. User {anchor:user} 用户实体 ||Name||Description||Schema|| |*age*\\ \\ _optional_||用户年龄||integer (int32)| |*id*\\ \\ _optional_||用户编号||integer (int64)| |*name*\\ \\ _optional_||用户姓名||string| ================================================ FILE: 2.x/chapter2-5/src/docs/confluence/generated/overview.txt ================================================ h1. spring-boot-starter-swagger h2. Overview {anchor:overview} Starter for swagger 2.x h3. Version information _Version_ : 1.9.0.RELEASE h3. Contact information _Contact_ : didi\\ _Contact Email_ : dyc87112@qq.com h3. License information _License_ : Apache License, Version 2.0\\ _License URL_ : https://www.apache.org/licenses/LICENSE-2.0.html\\ _Terms of service_ : https://github.com/dyc87112/spring-boot-starter-swagger h3. URI scheme _Host_ : localhost:8080\\ _BasePath_ : / h3. Tags * 用户管理 : User Controller ================================================ FILE: 2.x/chapter2-5/src/docs/confluence/generated/paths.txt ================================================ h2. Paths {anchor:paths} h3. 创建用户 {anchor:postuserusingpost} {noformat} POST /users/ {noformat} h4. Description 根据User对象创建用户 h4. Parameters ||Type||Name||Description||Schema|| |*Body*|*user*\\ \\ _required_||user||[User|#user]| h4. Responses ||HTTP Code||Description||Schema|| |*200*||OK||string| |*201*||Created||No Content| |*401*||Unauthorized||No Content| |*403*||Forbidden||No Content| |*404*||Not Found||No Content| h4. Consumes * {noformat}application/json{noformat} h4. Produces * {noformat}\*/*{noformat} h4. Tags * 用户管理 h4. Security ||Type||Name||Scopes|| |*apiKey*|*[Authorization|#authorization]*||global| h3. 获取用户列表 {anchor:getuserlistusingget} {noformat} GET /users/ {noformat} h4. Responses ||HTTP Code||Description||Schema|| |*200*||OK||< [User|#user] > array| |*401*||Unauthorized||No Content| |*403*||Forbidden||No Content| |*404*||Not Found||No Content| h4. Produces * {noformat}\*/*{noformat} h4. Tags * 用户管理 h4. Security ||Type||Name||Scopes|| |*apiKey*|*[Authorization|#authorization]*||global| h3. 获取用户详细信息 {anchor:getuserusingget} {noformat} GET /users/{id} {noformat} h4. Description 根据url的id来获取用户详细信息 h4. Parameters ||Type||Name||Description||Schema|| |*Path*|*id*\\ \\ _required_||id||integer (int64)| h4. Responses ||HTTP Code||Description||Schema|| |*200*||OK||[User|#user]| |*401*||Unauthorized||No Content| |*403*||Forbidden||No Content| |*404*||Not Found||No Content| h4. Produces * {noformat}\*/*{noformat} h4. Tags * 用户管理 h4. Security ||Type||Name||Scopes|| |*apiKey*|*[Authorization|#authorization]*||global| h3. 更新用户详细信息 {anchor:putuserusingput} {noformat} PUT /users/{id} {noformat} h4. Description 根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息 h4. Parameters ||Type||Name||Description||Schema|| |*Path*|*id*\\ \\ _required_||用户编号||integer (int64)| |*Body*|*user*\\ \\ _required_||user||[User|#user]| h4. Responses ||HTTP Code||Description||Schema|| |*200*||OK||string| |*201*||Created||No Content| |*401*||Unauthorized||No Content| |*403*||Forbidden||No Content| |*404*||Not Found||No Content| h4. Consumes * {noformat}application/json{noformat} h4. Produces * {noformat}\*/*{noformat} h4. Tags * 用户管理 h4. Security ||Type||Name||Scopes|| |*apiKey*|*[Authorization|#authorization]*||global| h3. 删除用户 {anchor:deleteuserusingdelete} {noformat} DELETE /users/{id} {noformat} h4. Description 根据url的id来指定删除对象 h4. Parameters ||Type||Name||Description||Schema|| |*Path*|*id*\\ \\ _required_||id||integer (int64)| h4. Responses ||HTTP Code||Description||Schema|| |*200*||OK||string| |*204*||No Content||No Content| |*401*||Unauthorized||No Content| |*403*||Forbidden||No Content| h4. Produces * {noformat}\*/*{noformat} h4. Tags * 用户管理 h4. Security ||Type||Name||Scopes|| |*apiKey*|*[Authorization|#authorization]*||global| ================================================ FILE: 2.x/chapter2-5/src/docs/confluence/generated/security.txt ================================================ h2. Security {anchor:securityscheme} h3. Authorization {anchor:authorization} _Type_ : apiKey\\ _Name_ : TOKEN\\ _In_ : HEADER ================================================ FILE: 2.x/chapter2-5/src/docs/markdown/generated/definitions.md ================================================ ## Definitions ### User 用户实体 |Name|Description|Schema| |---|---|---| |**age**
*optional*|用户年龄|integer (int32)| |**id**
*optional*|用户编号|integer (int64)| |**name**
*optional*|用户姓名|string| ================================================ FILE: 2.x/chapter2-5/src/docs/markdown/generated/overview.md ================================================ # spring-boot-starter-swagger ## Overview Starter for swagger 2.x ### Version information *Version* : 1.9.0.RELEASE ### Contact information *Contact* : didi *Contact Email* : dyc87112@qq.com ### License information *License* : Apache License, Version 2.0 *License URL* : https://www.apache.org/licenses/LICENSE-2.0.html *Terms of service* : https://github.com/dyc87112/spring-boot-starter-swagger ### URI scheme *Host* : localhost:8080 *BasePath* : / ### Tags * 用户管理 : User Controller ================================================ FILE: 2.x/chapter2-5/src/docs/markdown/generated/paths.md ================================================ ## Paths ### 创建用户 ``` POST /users/ ``` #### Description 根据User对象创建用户 #### Parameters |Type|Name|Description|Schema| |---|---|---|---| |**Body**|**user**
*required*|user|[User](#user)| #### Responses |HTTP Code|Description|Schema| |---|---|---| |**200**|OK|string| |**201**|Created|No Content| |**401**|Unauthorized|No Content| |**403**|Forbidden|No Content| |**404**|Not Found|No Content| #### Consumes * `application/json` #### Produces * `\*/*` #### Tags * 用户管理 #### Security |Type|Name|Scopes| |---|---|---| |**apiKey**|**[Authorization](#authorization)**|global| ### 获取用户列表 ``` GET /users/ ``` #### Responses |HTTP Code|Description|Schema| |---|---|---| |**200**|OK|< [User](#user) > array| |**401**|Unauthorized|No Content| |**403**|Forbidden|No Content| |**404**|Not Found|No Content| #### Produces * `\*/*` #### Tags * 用户管理 #### Security |Type|Name|Scopes| |---|---|---| |**apiKey**|**[Authorization](#authorization)**|global| ### 获取用户详细信息 ``` GET /users/{id} ``` #### Description 根据url的id来获取用户详细信息 #### Parameters |Type|Name|Description|Schema| |---|---|---|---| |**Path**|**id**
*required*|id|integer (int64)| #### Responses |HTTP Code|Description|Schema| |---|---|---| |**200**|OK|[User](#user)| |**401**|Unauthorized|No Content| |**403**|Forbidden|No Content| |**404**|Not Found|No Content| #### Produces * `\*/*` #### Tags * 用户管理 #### Security |Type|Name|Scopes| |---|---|---| |**apiKey**|**[Authorization](#authorization)**|global| ### 更新用户详细信息 ``` PUT /users/{id} ``` #### Description 根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息 #### Parameters |Type|Name|Description|Schema| |---|---|---|---| |**Path**|**id**
*required*|用户编号|integer (int64)| |**Body**|**user**
*required*|user|[User](#user)| #### Responses |HTTP Code|Description|Schema| |---|---|---| |**200**|OK|string| |**201**|Created|No Content| |**401**|Unauthorized|No Content| |**403**|Forbidden|No Content| |**404**|Not Found|No Content| #### Consumes * `application/json` #### Produces * `\*/*` #### Tags * 用户管理 #### Security |Type|Name|Scopes| |---|---|---| |**apiKey**|**[Authorization](#authorization)**|global| ### 删除用户 ``` DELETE /users/{id} ``` #### Description 根据url的id来指定删除对象 #### Parameters |Type|Name|Description|Schema| |---|---|---|---| |**Path**|**id**
*required*|id|integer (int64)| #### Responses |HTTP Code|Description|Schema| |---|---|---| |**200**|OK|string| |**204**|No Content|No Content| |**401**|Unauthorized|No Content| |**403**|Forbidden|No Content| #### Produces * `\*/*` #### Tags * 用户管理 #### Security |Type|Name|Scopes| |---|---|---| |**apiKey**|**[Authorization](#authorization)**|global| ================================================ FILE: 2.x/chapter2-5/src/docs/markdown/generated/security.md ================================================ ## Security ### Authorization *Type* : apiKey *Name* : TOKEN *In* : HEADER ================================================ FILE: 2.x/chapter2-5/src/main/java/com/didispace/chapter25/Chapter25Application.java ================================================ package com.didispace.chapter25; import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableSwagger2Doc @SpringBootApplication public class Chapter25Application { public static void main(String[] args) { SpringApplication.run(Chapter25Application.class, args); } } ================================================ FILE: 2.x/chapter2-5/src/main/java/com/didispace/chapter25/User.java ================================================ package com.didispace.chapter25; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(description="用户实体") public class User { @ApiModelProperty("用户编号") private Long id; @ApiModelProperty("用户姓名") private String name; @ApiModelProperty("用户年龄") private Integer age; } ================================================ FILE: 2.x/chapter2-5/src/main/java/com/didispace/chapter25/UserController.java ================================================ package com.didispace.chapter25; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import java.util.*; @Api(tags = "用户管理") @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下 public class UserController { // 创建线程安全的Map,模拟users信息的存储 static Map users = Collections.synchronizedMap(new HashMap<>()); @GetMapping("/") @ApiOperation(value = "获取用户列表") public List getUserList() { List r = new ArrayList<>(users.values()); return r; } @PostMapping("/") @ApiOperation(value = "创建用户", notes = "根据User对象创建用户") public String postUser(@RequestBody User user) { users.put(user.getId(), user); return "success"; } @GetMapping("/{id}") @ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息") public User getUser(@PathVariable Long id) { return users.get(id); } @PutMapping("/{id}") @ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "用户编号", required = true, example = "1") @ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @DeleteMapping("/{id}") @ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象") public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 2.x/chapter2-5/src/main/resources/application.properties ================================================ swagger.title=spring-boot-starter-swagger swagger.description=Starter for swagger 2.x swagger.version=1.9.0.RELEASE swagger.license=Apache License, Version 2.0 swagger.licenseUrl=https://www.apache.org/licenses/LICENSE-2.0.html swagger.termsOfServiceUrl=https://github.com/dyc87112/spring-boot-starter-swagger swagger.contact.name=didi swagger.contact.url=http://blog.didispace.com swagger.contact.email=dyc87112@qq.com swagger.base-package=com.didispace swagger.base-path=/** ================================================ FILE: 2.x/chapter2-5/src/test/java/com/didispace/chapter25/DemoApplicationTests.java ================================================ package com.didispace.chapter25; import io.github.swagger2markup.Swagger2MarkupConfig; import io.github.swagger2markup.Swagger2MarkupConverter; import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder; import io.github.swagger2markup.markup.builder.MarkupLanguage; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class DemoApplicationTests { @Test public void generateAsciiDocs() throws Exception { URL remoteSwaggerFile = new URL("http://localhost:8080/v2/api-docs"); Path outputDirectory = Paths.get("src/docs/asciidoc/generated"); // 输出Ascii格式 Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .build(); Swagger2MarkupConverter.from(remoteSwaggerFile) .withConfig(config) .build() .toFolder(outputDirectory); } @Test public void generateMarkdownDocs() throws Exception { URL remoteSwaggerFile = new URL("http://localhost:8080/v2/api-docs"); Path outputDirectory = Paths.get("src/docs/markdown/generated"); // 输出Ascii格式 Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.MARKDOWN) .build(); Swagger2MarkupConverter.from(remoteSwaggerFile) .withConfig(config) .build() .toFolder(outputDirectory); } @Test public void generateConfluenceDocs() throws Exception { URL remoteSwaggerFile = new URL("http://localhost:8080/v2/api-docs"); Path outputDirectory = Paths.get("src/docs/confluence/generated"); // 输出Ascii格式 Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP) .build(); Swagger2MarkupConverter.from(remoteSwaggerFile) .withConfig(config) .build() .toFolder(outputDirectory); } } ================================================ FILE: 2.x/chapter2-6/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter2-6/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter2-6 0.0.1-SNAPSHOT 找回启动日志中的请求路径列表 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter2-6/src/main/java/com/didispace/chapter26/Chapter26Application.java ================================================ package com.didispace.chapter26; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter26Application { public static void main(String[] args) { SpringApplication.run(Chapter26Application.class, args); } } ================================================ FILE: 2.x/chapter2-6/src/main/java/com/didispace/chapter26/User.java ================================================ package com.didispace.chapter26; import lombok.Data; @Data public class User { private Long id; private String name; private Integer age; } ================================================ FILE: 2.x/chapter2-6/src/main/java/com/didispace/chapter26/UserController.java ================================================ package com.didispace.chapter26; import org.springframework.web.bind.annotation.*; import java.util.*; @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下 public class UserController { // 创建线程安全的Map,模拟users信息的存储 static Map users = Collections.synchronizedMap(new HashMap<>()); @GetMapping("/") public List getUserList() { List r = new ArrayList<>(users.values()); return r; } @PostMapping("/") public String postUser(@RequestBody User user) { users.put(user.getId(), user); return "success"; } @GetMapping("/{id}") public User getUser(@PathVariable Long id) { return users.get(id); } @PutMapping("/{id}") public String putUser(@PathVariable Long id, @RequestBody User user) { User u = users.get(id); u.setName(user.getName()); u.setAge(user.getAge()); users.put(id, u); return "success"; } @DeleteMapping("/{id}") public String deleteUser(@PathVariable Long id) { users.remove(id); return "success"; } } ================================================ FILE: 2.x/chapter2-6/src/main/resources/application.properties ================================================ # 打印RequestMapping中的所有接口信息 logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=trace ================================================ FILE: 2.x/chapter2-7/.gitignore ================================================ target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### nbproject/private/ build/ nbbuild/ dist/ nbdist/ .nb-gradle/ ================================================ FILE: 2.x/chapter2-7/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.3.RELEASE com.didispace chapter2-7 0.0.1-SNAPSHOT 使用SpringFox3生成Swagger文档 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test io.springfox springfox-boot-starter 3.0.0 org.projectlombok lombok provided org.springframework.boot spring-boot-maven-plugin false jcenter-releases jcenter http://jcenter.bintray.com ================================================ FILE: 2.x/chapter2-7/src/main/java/com/didispace/chapter27/Chapter27Application.java ================================================ package com.didispace.chapter27; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import springfox.documentation.oas.annotations.EnableOpenApi; @EnableOpenApi @SpringBootApplication public class Chapter27Application { public static void main(String[] args) { SpringApplication.run(Chapter27Application.class, args); } } ================================================ FILE: 2.x/chapter2-7/src/main/java/com/didispace/chapter27/User.java ================================================ package com.didispace.demo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.*; @Data @NoArgsConstructor @AllArgsConstructor @ApiModel("用户基本信息") public class User { @ApiModelProperty("姓名") @Size(max = 20) private String name; @ApiModelProperty("年龄") @Max(150) @Min(1) private Integer age; @NotNull private String address; @Pattern(regexp = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$") private String email; } ================================================ FILE: 2.x/chapter2-7/src/main/java/com/didispace/chapter27/UserController.java ================================================ package com.didispace.demo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; @Api(tags="用户管理") @RestController public class UserController { @ApiOperation("创建用户") @PostMapping("/users") public User create(@RequestBody @Valid User user) { return user; } @ApiOperation("用户详情") @GetMapping("/users/{id}") public User findById(@PathVariable Long id) { return new User("bbb", 21, "上海", "aaa@bbb.com"); } @ApiOperation("用户列表") @GetMapping("/users") public List list(@ApiParam("查看第几页") @RequestParam int pageIndex, @ApiParam("每页多少条") @RequestParam int pageSize) { List result = new ArrayList<>(); result.add(new User("aaa", 50, "北京", "aaa@ccc.com")); result.add(new User("bbb", 21, "广州", "aaa@ddd.com")); return result; } @ApiIgnore @DeleteMapping("/users/{id}") public String deleteById(@PathVariable Long id) { return "delete user : " + id; } } ================================================ FILE: 2.x/chapter2-7/src/main/resources/application.properties ================================================ logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=trace ================================================ FILE: 2.x/chapter2-8/pom.xml ================================================ 4.0.0 com.didispace chapter2-8 1.0.0 jar 如何扩展XML格式的请求和响应 org.springframework.boot spring-boot-starter-parent 2.5.1 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test com.fasterxml.jackson.dataformat jackson-dataformat-xml org.projectlombok lombok org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter2-8/src/main/java/com/didispace/chapter28/Chapter28Application.java ================================================ package com.didispace.chapter28; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @SpringBootApplication public class Chapter28Application { public static void main(String[] args) { SpringApplication.run(Chapter28Application.class, args); } } ================================================ FILE: 2.x/chapter2-8/src/main/java/com/didispace/chapter28/User.java ================================================ package com.didispace.chapter28; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @Data @NoArgsConstructor @AllArgsConstructor @JacksonXmlRootElement(localName = "User") public class User { @JacksonXmlProperty(localName = "name") private String name; @JacksonXmlProperty(localName = "age") private Integer age; } ================================================ FILE: 2.x/chapter2-8/src/main/java/com/didispace/chapter28/UserController.java ================================================ package com.didispace.chapter28; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class UserController { @PostMapping(value = "/user", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE) @ResponseBody public User create(@RequestBody User user) { user.setName("didispace.com : " + user.getName()); user.setAge(user.getAge() + 100); return user; } } ================================================ FILE: 2.x/chapter2-8/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter2-9/pom.xml ================================================ 4.0.0 com.didispace chapter2-9 1.0.0 jar org.springframework.boot spring-boot-starter-parent 2.5.1 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.experimental graphql-spring-boot-starter 1.0.0-SNAPSHOT org.springframework.boot spring-boot-starter-test test com.fasterxml.jackson.dataformat jackson-dataformat-xml org.projectlombok lombok provided org.springframework.boot spring-boot-maven-plugin spring-snapshots https://repo.spring.io/snapshot true spring-milestones https://repo.spring.io/milestone ================================================ FILE: 2.x/chapter2-9/src/main/java/com/didispace/chapter29/Chapter29Application.java ================================================ package com.didispace.chapter29; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @SpringBootApplication public class Chapter29Application { public static void main(String[] args) { SpringApplication.run(Chapter29Application.class, args); } } ================================================ FILE: 2.x/chapter2-9/src/main/java/com/didispace/chapter29/User.java ================================================ package com.didispace.chapter29; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @Data @NoArgsConstructor @AllArgsConstructor @JacksonXmlRootElement(localName = "User") public class User { @JacksonXmlProperty(localName = "name") private String name; @JacksonXmlProperty(localName = "age") private Integer age; } ================================================ FILE: 2.x/chapter2-9/src/main/java/com/didispace/chapter29/UserController.java ================================================ package com.didispace.chapter29; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class UserController { @PostMapping(value = "/user", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE) @ResponseBody public User create(@RequestBody User user) { user.setName("didispace.com : " + user.getName()); user.setAge(user.getAge() + 100); return user; } } ================================================ FILE: 2.x/chapter2-9/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter3-1/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-1 0.0.1-SNAPSHOT 使用JdbcTemplate访问MySQL数据库 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-1/src/main/java/com/didispace/chapter31/Chapter31Application.java ================================================ package com.didispace.chapter31; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter31Application { public static void main(String[] args) { SpringApplication.run(Chapter31Application.class, args); } } ================================================ FILE: 2.x/chapter3-1/src/main/java/com/didispace/chapter31/User.java ================================================ package com.didispace.chapter31; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class User { private String name; private Integer age; } ================================================ FILE: 2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserService.java ================================================ package com.didispace.chapter31; import java.util.List; public interface UserService { /** * 新增一个用户 * * @param name * @param age */ int create(String name, Integer age); /** * 根据name查询用户 * * @param name * @return */ List getByName(String name); /** * 根据name删除用户 * * @param name */ int deleteByName(String name); /** * 获取用户总量 */ int getAllUsers(); /** * 删除所有用户 */ int deleteAllUsers(); } ================================================ FILE: 2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserServiceImpl.java ================================================ package com.didispace.chapter31; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @Service public class UserServiceImpl implements UserService { private JdbcTemplate jdbcTemplate; UserServiceImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public int create(String name, Integer age) { return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age); } @Override public List getByName(String name) { List users = jdbcTemplate.query("select NAME, AGE from USER where NAME = ?", (resultSet, i) -> { User user = new User(); user.setName(resultSet.getString("NAME")); user.setAge(resultSet.getInt("AGE")); return user; }, name); return users; } @Override public int deleteByName(String name) { return jdbcTemplate.update("delete from USER where NAME = ?", name); } @Override public int getAllUsers() { return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class); } @Override public int deleteAllUsers() { return jdbcTemplate.update("delete from USER"); } } ================================================ FILE: 2.x/chapter3-1/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ================================================ FILE: 2.x/chapter3-1/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java ================================================ package com.didispace.chapter31; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import java.util.List; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest public class Chapter31ApplicationTests { @Autowired private UserService userSerivce; @Before public void setUp() { // 准备,清空user表 userSerivce.deleteAllUsers(); } @Test public void test() throws Exception { // 插入5个用户 userSerivce.create("Tom", 10); userSerivce.create("Mike", 11); userSerivce.create("Didispace", 30); userSerivce.create("Oscar", 21); userSerivce.create("Linda", 17); // 查询名为Oscar的用户,判断年龄是否匹配 List userList = userSerivce.getByName("Oscar"); Assert.assertEquals(21, userList.get(0).getAge().intValue()); // 查数据库,应该有5个用户 Assert.assertEquals(5, userSerivce.getAllUsers()); // 删除两个用户 userSerivce.deleteByName("Tom"); userSerivce.deleteByName("Mike"); // 查数据库,应该有5个用户 Assert.assertEquals(3, userSerivce.getAllUsers()); } } ================================================ FILE: 2.x/chapter3-10/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-10/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-10 0.0.1-SNAPSHOT 事务管理入门 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-10/src/main/java/com/didispace/chapter310/Chapter310Application.java ================================================ package com.didispace.chapter310; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Chapter310Application { public static void main(String[] args) { SpringApplication.run(Chapter310Application.class, args); } @RestController static class TextController { @GetMapping("/hello") public String hello() { return "hello world"; } } } ================================================ FILE: 2.x/chapter3-10/src/main/java/com/didispace/chapter310/User.java ================================================ package com.didispace.chapter310; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; import javax.validation.constraints.Max; @Entity @Data @NoArgsConstructor public class User { @Id @GeneratedValue private Long id; private String name; @Max(50) private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-10/src/main/java/com/didispace/chapter310/UserRepository.java ================================================ package com.didispace.chapter310; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/7/9. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserRepository extends JpaRepository { User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name); } ================================================ FILE: 2.x/chapter3-10/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.hibernate.ddl-auto=create ================================================ FILE: 2.x/chapter3-10/src/test/java/com/didispace/chapter310/Chapter310ApplicationTests.java ================================================ package com.didispace.chapter310; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter310ApplicationTests { @Autowired private UserRepository userRepository; @Test @Transactional public void test() throws Exception { // 创建10条记录 userRepository.save(new User("AAA", 10)); userRepository.save(new User("BBB", 20)); userRepository.save(new User("CCC", 30)); userRepository.save(new User("DDD", 40)); userRepository.save(new User("EEE", 50)); userRepository.save(new User("FFF", 60)); userRepository.save(new User("GGG", 70)); userRepository.save(new User("HHH", 80)); userRepository.save(new User("III", 90)); userRepository.save(new User("JJJ", 100)); // 测试findAll, 查询所有记录 Assert.assertEquals(10, userRepository.findAll().size()); // 测试findByName, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue()); // 测试findUser, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue()); // 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName()); // 测试删除姓名为AAA的User userRepository.delete(userRepository.findByName("AAA")); // 测试findAll, 查询所有记录, 验证上面的删除是否成功 Assert.assertEquals(9, userRepository.findAll().size()); } } ================================================ FILE: 2.x/chapter3-11/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-11/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter3-11 0.0.1-SNAPSHOT 使用Flyway管理数据库版本 1.8 org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java org.flywaydb flyway-core org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/Chapter311Application.java ================================================ package com.didispace.chapter311; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter311Application { public static void main(String[] args) { SpringApplication.run(Chapter311Application.class, args); } } ================================================ FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/User.java ================================================ package com.didispace.chapter311; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class User { private Long id; private String name; private Integer age; } ================================================ FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserService.java ================================================ package com.didispace.chapter311; import java.util.List; public interface UserService { /** * 新增一个用户 * * @param name * @param age */ int create(String name, Integer age); /** * 根据name查询用户 * * @param name * @return */ List getByName(String name); /** * 根据name删除用户 * * @param name */ int deleteByName(String name); /** * 获取用户总量 */ int getAllUsers(); /** * 删除所有用户 */ int deleteAllUsers(); } ================================================ FILE: 2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserServiceImpl.java ================================================ package com.didispace.chapter311; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService { private JdbcTemplate jdbcTemplate; UserServiceImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public int create(String name, Integer age) { return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age); } @Override public List getByName(String name) { List users = jdbcTemplate.query("select * from USER where NAME = ?", (resultSet, i) -> { User user = new User(); user.setId(resultSet.getLong("ID")); user.setName(resultSet.getString("NAME")); user.setAge(resultSet.getInt("AGE")); return user; }, name); return users; } @Override public int deleteByName(String name) { return jdbcTemplate.update("delete from USER where NAME = ?", name); } @Override public int getAllUsers() { return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class); } @Override public int deleteAllUsers() { return jdbcTemplate.update("delete from USER"); } } ================================================ FILE: 2.x/chapter3-11/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.flyway.locations=classpath:db/migration ================================================ FILE: 2.x/chapter3-11/src/main/resources/db/migration/V1_1__alter_table_user.sql ================================================ ALTER TABLE `user` ADD COLUMN `address` VARCHAR(20) DEFAULT NULL; ================================================ FILE: 2.x/chapter3-11/src/main/resources/db/migration/V1__Base_version.sql ================================================ DROP TABLE IF EXISTS user ; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(20) NOT NULL COMMENT '姓名', `age` int(5) DEFAULT NULL COMMENT '年龄', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ================================================ FILE: 2.x/chapter3-11/src/test/java/com/didispace/chapter311/Chapter311ApplicationTests.java ================================================ package com.didispace.chapter311; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; @Slf4j @SpringBootTest public class Chapter311ApplicationTests { @Autowired private UserService userSerivce; @Test public void test() throws Exception { userSerivce.deleteAllUsers(); // 插入5个用户 userSerivce.create("Tom", 10); userSerivce.create("Mike", 11); userSerivce.create("Didispace", 30); userSerivce.create("Oscar", 21); userSerivce.create("Linda", 17); // 查询名为Oscar的用户,判断年龄是否匹配 List userList = userSerivce.getByName("Oscar"); Assertions.assertEquals(21, userList.get(0).getAge().intValue()); // 查数据库,应该有5个用户 Assertions.assertEquals(5, userSerivce.getAllUsers()); // 删除两个用户 userSerivce.deleteByName("Tom"); userSerivce.deleteByName("Mike"); // 查数据库,应该有5个用户 Assertions.assertEquals(3, userSerivce.getAllUsers()); } } ================================================ FILE: 2.x/chapter3-12/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-12/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.2 com.didispace chapter3-12 0.0.1-SNAPSHOT 使用JTA实现多数据源的事务 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-jta-atomikos mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-12/src/main/java/com/didispace/chapter312/Chapter312Application.java ================================================ package com.didispace.chapter312; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter312Application { public static void main(String[] args) { SpringApplication.run(Chapter312Application.class, args); } } ================================================ FILE: 2.x/chapter3-12/src/main/java/com/didispace/chapter312/DataSourceConfiguration.java ================================================ package com.didispace.chapter312; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class DataSourceConfiguration { @Primary @Bean @ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.primary") public DataSource primaryDataSource() { return new AtomikosDataSourceBean(); } @Bean @ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.secondary") public DataSource secondaryDataSource() { return new AtomikosDataSourceBean(); } @Bean public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource primaryDataSource) { return new JdbcTemplate(primaryDataSource); } @Bean public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) { return new JdbcTemplate(secondaryDataSource); } } ================================================ FILE: 2.x/chapter3-12/src/main/java/com/didispace/chapter312/TestService.java ================================================ package com.didispace.chapter312; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class TestService { private JdbcTemplate primaryJdbcTemplate; private JdbcTemplate secondaryJdbcTemplate; public TestService(JdbcTemplate primaryJdbcTemplate, JdbcTemplate secondaryJdbcTemplate) { this.primaryJdbcTemplate = primaryJdbcTemplate; this.secondaryJdbcTemplate = secondaryJdbcTemplate; } @Transactional public void tx() { // 修改test1库中的数据 primaryJdbcTemplate.update("update user set age = ? where name = ?", 30, "aaa"); // 修改test2库中的数据 secondaryJdbcTemplate.update("update user set age = ? where name = ?", 30, "aaa"); } @Transactional public void tx2() { // 修改test1库中的数据 primaryJdbcTemplate.update("update user set age = ? where name = ?", 40, "aaa"); // 模拟:修改test2库之前抛出异常 throw new RuntimeException(); } } ================================================ FILE: 2.x/chapter3-12/src/main/resources/application.properties ================================================ spring.jta.enabled=true spring.jta.atomikos.datasource.primary.xa-properties.url=jdbc:mysql://localhost:3306/test1 spring.jta.atomikos.datasource.primary.xa-properties.user=root spring.jta.atomikos.datasource.primary.xa-properties.password=12345678 spring.jta.atomikos.datasource.primary.xa-data-source-class-name=com.mysql.cj.jdbc.MysqlXADataSource spring.jta.atomikos.datasource.primary.unique-resource-name=test1 spring.jta.atomikos.datasource.primary.max-pool-size=25 spring.jta.atomikos.datasource.primary.min-pool-size=3 spring.jta.atomikos.datasource.primary.max-lifetime=20000 spring.jta.atomikos.datasource.primary.borrow-connection-timeout=10000 spring.jta.atomikos.datasource.secondary.xa-properties.url=jdbc:mysql://localhost:3306/test2 spring.jta.atomikos.datasource.secondary.xa-properties.user=root spring.jta.atomikos.datasource.secondary.xa-properties.password=12345678 spring.jta.atomikos.datasource.secondary.xa-data-source-class-name=com.mysql.cj.jdbc.MysqlXADataSource spring.jta.atomikos.datasource.secondary.unique-resource-name=test2 spring.jta.atomikos.datasource.secondary.max-pool-size=25 spring.jta.atomikos.datasource.secondary.min-pool-size=3 spring.jta.atomikos.datasource.secondary.max-lifetime=20000 spring.jta.atomikos.datasource.secondary.borrow-connection-timeout=10000 #spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1 #spring.datasource.primary.username=root #spring.datasource.primary.password=12345678 #spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver # #spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2 #spring.datasource.secondary.username=root #spring.datasource.secondary.password=12345678 #spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver ================================================ FILE: 2.x/chapter3-12/src/test/java/com/didispace/chapter312/Chapter312ApplicationTests.java ================================================ package com.didispace.chapter312; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.annotation.Transactional; @SpringBootTest(classes = Chapter312Application.class) public class Chapter312ApplicationTests { @Autowired protected JdbcTemplate primaryJdbcTemplate; @Autowired protected JdbcTemplate secondaryJdbcTemplate; @Autowired private TestService testService; @Test public void test1() throws Exception { // 正确更新的情况 testService.tx(); Assertions.assertEquals(30, primaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa")); Assertions.assertEquals(30, secondaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa")); } @Test public void test2() throws Exception { // 更新失败的情况 try { testService.tx2(); } catch (Exception e) { e.printStackTrace(); } finally { // 部分更新失败,test1中的更新应该回滚 Assertions.assertEquals(30, primaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa")); Assertions.assertEquals(30, secondaryJdbcTemplate.queryForObject("select age from user where name=?", Integer.class, "aaa")); } } } ================================================ FILE: 2.x/chapter3-13/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-13/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.0 com.didispace chapter3-13 0.0.1-SNAPSHOT 2.5版本之后的数据脚本初始化 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-13/src/main/java/com/didispace/chapter313/Chapter313Application.java ================================================ package com.didispace.chapter313; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter313Application { public static void main(String[] args) { SpringApplication.run(Chapter313Application.class, args); } } ================================================ FILE: 2.x/chapter3-13/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # Spring Boot 2.5.0 init schema & data spring.sql.init.username=root spring.sql.init.password= spring.sql.init.schema-locations=classpath*:schema-all.sql #spring.sql.init.enabled=true #spring.sql.init.data-locations=classpath*: #spring.sql.init.encoding=UTF-8 #spring.sql.init.separator=; #spring.sql.init.continue-on-error=true ================================================ FILE: 2.x/chapter3-13/src/main/resources/schema-all.sql ================================================ create table test.user_info ( id int unsigned auto_increment comment '用户id' primary key, open_id varchar(255) default '' null comment '微信小程序openid', nick_name varchar(255) default '' null comment '微信名', head_img varchar(255) default '' null comment '微信头像', sex varchar(255) default '' null comment '性别', phone varchar(255) default '' null comment '手机', province varchar(255) default '' null comment '注册地址:省', city varchar(255) default '' null comment '注册地址:城市', country varchar(255) default '' null comment '注册地址:县/区', status tinyint unsigned default 0 not null comment '是否标记删除 0:否 1:是', create_time datetime not null comment '创建时间', update_time datetime not null comment '更新时间' ) comment '用户表'; ================================================ FILE: 2.x/chapter3-13/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java ================================================ package com.didispace.chapter31; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class Chapter31ApplicationTests { @Test public void test() throws Exception { } } ================================================ FILE: 2.x/chapter3-2/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-2 0.0.1-SNAPSHOT 默认数据源Hikari的配置详解 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/Chapter32Application.java ================================================ package com.didispace.chapter32; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter32Application { public static void main(String[] args) { SpringApplication.run(Chapter32Application.class, args); } } ================================================ FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/User.java ================================================ package com.didispace.chapter32; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class User { private String name; private Integer age; } ================================================ FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserService.java ================================================ package com.didispace.chapter32; import java.util.List; public interface UserService { /** * 新增一个用户 * * @param name * @param age */ int create(String name, Integer age); /** * 根据name查询用户 * * @param name * @return */ List getByName(String name); /** * 根据name删除用户 * * @param name */ int deleteByName(String name); /** * 获取用户总量 */ int getAllUsers(); /** * 删除所有用户 */ int deleteAllUsers(); } ================================================ FILE: 2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserServiceImpl.java ================================================ package com.didispace.chapter32; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @Service public class UserServiceImpl implements UserService { private JdbcTemplate jdbcTemplate; UserServiceImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public int create(String name, Integer age) { return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age); } @Override public List getByName(String name) { List users = jdbcTemplate.query("select NAME, AGE from USER where NAME = ?", (resultSet, i) -> { User user = new User(); user.setName(resultSet.getString("NAME")); user.setAge(resultSet.getInt("AGE")); return user; }, name); return users; } @Override public int deleteByName(String name) { return jdbcTemplate.update("delete from USER where NAME = ?", name); } @Override public int getAllUsers() { return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class); } @Override public int deleteAllUsers() { return jdbcTemplate.update("delete from USER"); } } ================================================ FILE: 2.x/chapter3-2/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size spring.datasource.hikari.minimum-idle=10 # 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 spring.datasource.hikari.maximum-pool-size=20 # 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 spring.datasource.hikari.idle-timeout=500000 # 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 spring.datasource.hikari.max-lifetime=540000 # 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 spring.datasource.hikari.connection-timeout=60000 # 用于测试连接是否可用的查询语句 spring.datasource.hikari.connection-test-query=SELECT 1 ================================================ FILE: 2.x/chapter3-2/src/test/java/com/didispace/chapter32/Chapter32ApplicationTests.java ================================================ package com.didispace.chapter32; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.util.List; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter32ApplicationTests { @Autowired private UserService userSerivce; @Autowired private DataSource dataSource; @Before public void setUp() { // 准备,清空user表 userSerivce.deleteAllUsers(); } @Test public void test() throws Exception { // 插入5个用户 userSerivce.create("Tom", 10); userSerivce.create("Mike", 11); userSerivce.create("Didispace", 30); userSerivce.create("Oscar", 21); userSerivce.create("Linda", 17); // 查询名为Oscar的用户,判断年龄是否匹配 List userList = userSerivce.getByName("Oscar"); Assert.assertEquals(21, userList.get(0).getAge().intValue()); // 查数据库,应该有5个用户 Assert.assertEquals(5, userSerivce.getAllUsers()); // 删除两个用户 userSerivce.deleteByName("Tom"); userSerivce.deleteByName("Mike"); // 查数据库,应该有5个用户 Assert.assertEquals(3, userSerivce.getAllUsers()); } } ================================================ FILE: 2.x/chapter3-3/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-3 0.0.1-SNAPSHOT 使用国产数据库连接池Druid 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc com.alibaba druid-spring-boot-starter 1.1.21 org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/Chapter33Application.java ================================================ package com.didispace.chapter33; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Chapter33Application { public static void main(String[] args) { SpringApplication.run(Chapter33Application.class, args); } @RestController static class TextController { @GetMapping("/hello") public String hello() { return "hello world"; } } } ================================================ FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/User.java ================================================ package com.didispace.chapter33; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class User { private String name; private Integer age; } ================================================ FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserController.java ================================================ package com.didispace.chapter33; import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.web.bind.annotation.*; import java.util.List; /** * Created by 程序猿DD/翟永超 on 2020/2/8. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @Data @AllArgsConstructor @RestController public class UserController { private UserService userService; @PostMapping("/user") public int create(@RequestBody User user) { return userService.create(user.getName(), user.getAge()); } @GetMapping("/user/{name}") public List getByName(@PathVariable String name) { return userService.getByName(name); } @DeleteMapping("/user/{name}") public int deleteByName(@PathVariable String name) { return userService.deleteByName(name); } @GetMapping("/user/count") public int getAllUsers() { return userService.getAllUsers(); } @DeleteMapping("/user/all") public int deleteAllUsers() { return userService.deleteAllUsers(); } } ================================================ FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserService.java ================================================ package com.didispace.chapter33; import java.util.List; public interface UserService { /** * 新增一个用户 * * @param name * @param age */ int create(String name, Integer age); /** * 根据name查询用户 * * @param name * @return */ List getByName(String name); /** * 根据name删除用户 * * @param name */ int deleteByName(String name); /** * 获取用户总量 */ int getAllUsers(); /** * 删除所有用户 */ int deleteAllUsers(); } ================================================ FILE: 2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserServiceImpl.java ================================================ package com.didispace.chapter33; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @Service public class UserServiceImpl implements UserService { private JdbcTemplate jdbcTemplate; UserServiceImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public int create(String name, Integer age) { return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age); } @Override public List getByName(String name) { List users = jdbcTemplate.query("select NAME, AGE from USER where NAME = ?", (resultSet, i) -> { User user = new User(); user.setName(resultSet.getString("NAME")); user.setAge(resultSet.getInt("AGE")); return user; }, name); return users; } @Override public int deleteByName(String name) { return jdbcTemplate.update("delete from USER where NAME = ?", name); } @Override public int getAllUsers() { return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class); } @Override public int deleteAllUsers() { return jdbcTemplate.update("delete from USER"); } } ================================================ FILE: 2.x/chapter3-3/src/main/resources/application.properties ================================================ # 基础配置 spring.datasource.druid.url=jdbc:mysql://localhost:3306/test spring.datasource.druid.username=root spring.datasource.druid.password= spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver # 连接池配置 spring.datasource.druid.initialSize=10 spring.datasource.druid.maxActive=20 spring.datasource.druid.maxWait=60000 spring.datasource.druid.minIdle=1 spring.datasource.druid.timeBetweenEvictionRunsMillis=60000 spring.datasource.druid.minEvictableIdleTimeMillis=300000 spring.datasource.druid.testWhileIdle=true spring.datasource.druid.testOnBorrow=true spring.datasource.druid.testOnReturn=false spring.datasource.druid.poolPreparedStatements=true spring.datasource.druid.maxOpenPreparedStatements=20 spring.datasource.druid.validationQuery=SELECT 1 spring.datasource.druid.validation-query-timeout=500 spring.datasource.druid.filters=stat,wall # 监控配置 spring.datasource.druid.stat-view-servlet.enabled=true spring.datasource.druid.stat-view-servlet.url-pattern=/druid/* spring.datasource.druid.stat-view-servlet.reset-enable=true spring.datasource.druid.stat-view-servlet.login-username=admin spring.datasource.druid.stat-view-servlet.login-password=admin ================================================ FILE: 2.x/chapter3-3/src/test/java/com/didispace/chapter33/Chapter33ApplicationTests.java ================================================ package com.didispace.chapter33; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.util.List; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter33ApplicationTests { @Autowired private UserService userSerivce; @Autowired private DataSource dataSource; @Before public void setUp() { // 准备,清空user表 userSerivce.deleteAllUsers(); } @Test public void test() throws Exception { // 插入5个用户 userSerivce.create("Tom", 10); userSerivce.create("Mike", 11); userSerivce.create("Didispace", 30); userSerivce.create("Oscar", 21); userSerivce.create("Linda", 17); // 查询名为Oscar的用户,判断年龄是否匹配 List userList = userSerivce.getByName("Oscar"); Assert.assertEquals(21, userList.get(0).getAge().intValue()); // 查数据库,应该有5个用户 Assert.assertEquals(5, userSerivce.getAllUsers()); // 删除两个用户 userSerivce.deleteByName("Tom"); userSerivce.deleteByName("Mike"); // 查数据库,应该有5个用户 Assert.assertEquals(3, userSerivce.getAllUsers()); } } ================================================ FILE: 2.x/chapter3-4/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-4/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-4 0.0.1-SNAPSHOT 使用Spring Data JPA访问MySQL 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-4/src/main/java/com/didispace/chapter34/Chapter34Application.java ================================================ package com.didispace.chapter34; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Chapter34Application { public static void main(String[] args) { SpringApplication.run(Chapter34Application.class, args); } @RestController static class TextController { @GetMapping("/hello") public String hello() { return "hello world"; } } } ================================================ FILE: 2.x/chapter3-4/src/main/java/com/didispace/chapter34/User.java ================================================ package com.didispace.chapter34; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity @Data @NoArgsConstructor public class User { @Id @GeneratedValue private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-4/src/main/java/com/didispace/chapter34/UserRepository.java ================================================ package com.didispace.chapter34; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/2/15. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserRepository extends JpaRepository { User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name); } ================================================ FILE: 2.x/chapter3-4/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop ================================================ FILE: 2.x/chapter3-4/src/test/java/com/didispace/chapter34/Chapter34ApplicationTests.java ================================================ package com.didispace.chapter34; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.sql.DataSource; import java.util.List; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter34ApplicationTests { @Autowired private UserRepository userRepository; @Test public void test() throws Exception { // 创建10条记录 userRepository.save(new User("AAA", 10)); userRepository.save(new User("BBB", 20)); userRepository.save(new User("CCC", 30)); userRepository.save(new User("DDD", 40)); userRepository.save(new User("EEE", 50)); userRepository.save(new User("FFF", 60)); userRepository.save(new User("GGG", 70)); userRepository.save(new User("HHH", 80)); userRepository.save(new User("III", 90)); userRepository.save(new User("JJJ", 100)); // 测试findAll, 查询所有记录 Assert.assertEquals(10, userRepository.findAll().size()); // 测试findByName, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue()); // 测试findUser, 查询姓名为FFF的User Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue()); // 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName()); // 测试删除姓名为AAA的User userRepository.delete(userRepository.findByName("AAA")); // 测试findAll, 查询所有记录, 验证上面的删除是否成功 Assert.assertEquals(9, userRepository.findAll().size()); } } ================================================ FILE: 2.x/chapter3-5/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-5/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-5 0.0.1-SNAPSHOT 使用MyBatis访问MySQL 1.8 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-5/src/main/java/com/didispace/chapter35/Chapter35Application.java ================================================ package com.didispace.chapter35; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter35Application { public static void main(String[] args) { SpringApplication.run(Chapter35Application.class, args); } } ================================================ FILE: 2.x/chapter3-5/src/main/java/com/didispace/chapter35/User.java ================================================ package com.didispace.chapter35; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class User { private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-5/src/main/java/com/didispace/chapter35/UserMapper.java ================================================ package com.didispace.chapter35; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; /** * Created by 程序猿DD/翟永超 on 2020/2/15. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @Mapper public interface UserMapper { @Select("SELECT * FROM USER WHERE NAME = #{name}") User findByName(@Param("name") String name); @Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})") int insert(@Param("name") String name, @Param("age") Integer age); } ================================================ FILE: 2.x/chapter3-5/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ================================================ FILE: 2.x/chapter3-5/src/test/java/com/didispace/chapter35/Chapter35ApplicationTests.java ================================================ package com.didispace.chapter35; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest @Transactional public class Chapter35ApplicationTests { @Autowired private UserMapper userMapper; @Test @Rollback public void test() throws Exception { userMapper.insert("AAA", 20); User u = userMapper.findByName("AAA"); Assert.assertEquals(20, u.getAge().intValue()); } } ================================================ FILE: 2.x/chapter3-6/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-6/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-6 0.0.1-SNAPSHOT 使用MyBatis(xml配置方式) 1.8 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-6/src/main/java/com/didispace/chapter36/Chapter36Application.java ================================================ package com.didispace.chapter36; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @MapperScan("com.didispace.chapter36.mapper") @SpringBootApplication public class Chapter36Application { public static void main(String[] args) { SpringApplication.run(Chapter36Application.class, args); } } ================================================ FILE: 2.x/chapter3-6/src/main/java/com/didispace/chapter36/entity/User.java ================================================ package com.didispace.chapter36.entity; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class User { private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-6/src/main/java/com/didispace/chapter36/mapper/UserMapper.java ================================================ package com.didispace.chapter36.mapper; import com.didispace.chapter36.entity.User; import org.apache.ibatis.annotations.Param; /** * Created by 程序猿DD/翟永超 on 2020/2/28. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserMapper { User findByName(@Param("name") String name); int insert(@Param("name") String name, @Param("age") Integer age); } ================================================ FILE: 2.x/chapter3-6/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver mybatis.mapper-locations=classpath:mapper/*.xml ================================================ FILE: 2.x/chapter3-6/src/main/resources/mapper/UserMapper.xml ================================================ INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age}) ================================================ FILE: 2.x/chapter3-6/src/test/java/com/didispace/chapter36/Chapter36ApplicationTests.java ================================================ package com.didispace.chapter36; import com.didispace.chapter36.entity.User; import com.didispace.chapter36.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest @Transactional public class Chapter36ApplicationTests { @Autowired private UserMapper userMapper; @Test @Rollback public void test() throws Exception { userMapper.insert("AAA", 20); User u = userMapper.findByName("AAA"); Assert.assertEquals(20, u.getAge().intValue()); } } ================================================ FILE: 2.x/chapter3-7/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-7/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-7 0.0.1-SNAPSHOT JdbcTemplate的多数据源配置 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-7/src/main/java/com/didispace/chapter37/Chapter37Application.java ================================================ package com.didispace.chapter37; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter37Application { public static void main(String[] args) { SpringApplication.run(Chapter37Application.class, args); } } ================================================ FILE: 2.x/chapter3-7/src/main/java/com/didispace/chapter37/DataSourceConfiguration.java ================================================ package com.didispace.chapter37; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class DataSourceConfiguration { @Primary @Bean @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource primaryDataSource) { return new JdbcTemplate(primaryDataSource); } @Bean public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) { return new JdbcTemplate(secondaryDataSource); } } ================================================ FILE: 2.x/chapter3-7/src/main/resources/application.properties ================================================ # pring boot 1.x的配置:spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=123456 spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver # spring boot 1.x的配置:spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=123456 spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver ================================================ FILE: 2.x/chapter3-7/src/test/java/com/didispace/chapter37/Chapter37ApplicationTests.java ================================================ package com.didispace.chapter37; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class Chapter37ApplicationTests { @Autowired protected JdbcTemplate primaryJdbcTemplate; @Autowired protected JdbcTemplate secondaryJdbcTemplate; @Before public void setUp() { primaryJdbcTemplate.update("DELETE FROM USER "); secondaryJdbcTemplate.update("DELETE FROM USER "); } @Test public void test() throws Exception { // 往第一个数据源中插入 2 条数据 primaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "aaa", 20); primaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "bbb", 30); // 往第二个数据源中插入 1 条数据,若插入的是第一个数据源,则会主键冲突报错 secondaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "ccc", 20); // 查一下第一个数据源中是否有 2 条数据,验证插入是否成功 Assert.assertEquals("2", primaryJdbcTemplate.queryForObject("select count(1) from user", String.class)); // 查一下第一个数据源中是否有 1 条数据,验证插入是否成功 Assert.assertEquals("1", secondaryJdbcTemplate.queryForObject("select count(1) from user", String.class)); } } ================================================ FILE: 2.x/chapter3-8/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-8/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-8 0.0.1-SNAPSHOT Spring Data JPA的多数据源配置 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/Chapter38Application.java ================================================ package com.didispace.chapter38; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Chapter38Application { public static void main(String[] args) { SpringApplication.run(Chapter38Application.class, args); } } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/DataSourceConfiguration.java ================================================ package com.didispace.chapter38; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class DataSourceConfiguration { @Primary @Bean @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/PrimaryConfig.java ================================================ package com.didispace.chapter38; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "com.didispace.chapter38.p" }) //设置Repository所在位置 public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; private Map getVendorProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Primary @Bean(name = "entityManagerFactoryPrimary") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) { // HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); // jpaVendorAdapter.setGenerateDdl(true); return builder .dataSource(primaryDataSource) .packages("com.didispace.chapter38.p") //设置实体类所在位置 .persistenceUnit("primaryPersistenceUnit") .properties(getVendorProperties()) .build(); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/SecondaryConfig.java ================================================ package com.didispace.chapter38; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "com.didispace.chapter38.s" }) //设置Repository所在位置 public class SecondaryConfig { @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; private Map getVendorProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) { return builder .dataSource(secondaryDataSource) .packages("com.didispace.chapter38.s") //设置实体类所在位置 .persistenceUnit("secondaryPersistenceUnit") .properties(getVendorProperties()) .build(); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/User.java ================================================ package com.didispace.chapter38.p; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity @Data @NoArgsConstructor public class User { @Id @GeneratedValue private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/UserRepository.java ================================================ package com.didispace.chapter38.p; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/6/22. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserRepository extends JpaRepository { } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/Message.java ================================================ package com.didispace.chapter38.s; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity @Data @NoArgsConstructor public class Message { @Id @GeneratedValue private Long id; private String title; private String message; public Message(String title, String message) { this.title = title; this.message = message; } } ================================================ FILE: 2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/MessageRepository.java ================================================ package com.didispace.chapter38.s; import org.springframework.data.jpa.repository.JpaRepository; /** * Created by 程序猿DD/翟永超 on 2020/6/22. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface MessageRepository extends JpaRepository { } ================================================ FILE: 2.x/chapter3-8/src/main/resources/application.properties ================================================ # pring boot 1.x的配置:spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=12345678 spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver # spring boot 1.x的配置:spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=12345678 spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver # 日志打印执行的SQL spring.jpa.show-sql=true # Hibernate的DDL策略 spring.jpa.hibernate.ddl-auto=create-drop ================================================ FILE: 2.x/chapter3-8/src/test/java/com/didispace/chapter38/Chapter38ApplicationTests.java ================================================ package com.didispace.chapter38; import com.didispace.chapter38.p.User; import com.didispace.chapter38.p.UserRepository; import com.didispace.chapter38.s.Message; import com.didispace.chapter38.s.MessageRepository; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter38ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private MessageRepository messageRepository; @Test public void test() throws Exception { userRepository.save(new User("aaa", 10)); userRepository.save(new User("bbb", 20)); userRepository.save(new User("ccc", 30)); userRepository.save(new User("ddd", 40)); userRepository.save(new User("eee", 50)); Assert.assertEquals(5, userRepository.findAll().size()); messageRepository.save(new Message("o1", "aaaaaaaaaa")); messageRepository.save(new Message("o2", "bbbbbbbbbb")); messageRepository.save(new Message("o3", "cccccccccc")); Assert.assertEquals(3, messageRepository.findAll().size()); } } ================================================ FILE: 2.x/chapter3-9/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter3-9/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter3-9 0.0.1-SNAPSHOT MyBatis的多数据源配置 1.8 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/Chapter39Application.java ================================================ package com.didispace.chapter39; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter39Application { public static void main(String[] args) { SpringApplication.run(Chapter39Application.class, args); } } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/DataSourceConfiguration.java ================================================ package com.didispace.chapter39; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceConfiguration { @Primary @Bean @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/PrimaryConfig.java ================================================ package com.didispace.chapter39; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration @MapperScan( basePackages = "com.didispace.chapter39.p", sqlSessionFactoryRef = "sqlSessionFactoryPrimary", sqlSessionTemplateRef = "sqlSessionTemplatePrimary") public class PrimaryConfig { private DataSource primaryDataSource; public PrimaryConfig(@Qualifier("primaryDataSource") DataSource primaryDataSource) { this.primaryDataSource = primaryDataSource; } @Bean public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(primaryDataSource); return bean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception { return new SqlSessionTemplate(sqlSessionFactoryPrimary()); } } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/SecondaryConfig.java ================================================ package com.didispace.chapter39; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration @MapperScan( basePackages = "com.didispace.chapter39.s", sqlSessionFactoryRef = "sqlSessionFactorySecondary", sqlSessionTemplateRef = "sqlSessionTemplateSecondary") public class SecondaryConfig { private DataSource secondaryDataSource; public SecondaryConfig(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) { this.secondaryDataSource = secondaryDataSource; } @Bean public SqlSessionFactory sqlSessionFactorySecondary() throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(secondaryDataSource); return bean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception { return new SqlSessionTemplate(sqlSessionFactorySecondary()); } } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/entity/UserPrimary.java ================================================ package com.didispace.chapter39.p.entity; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class UserPrimary { private Long id; private String name; private Integer age; public UserPrimary(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/mapper/UserMapperPrimary.java ================================================ package com.didispace.chapter39.p.mapper; import com.didispace.chapter39.p.entity.UserPrimary; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; /** * Created by 程序猿DD/翟永超 on 2020/2/28. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserMapperPrimary { @Select("SELECT * FROM USER WHERE NAME = #{name}") UserPrimary findByName(@Param("name") String name); @Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})") int insert(@Param("name") String name, @Param("age") Integer age); @Delete("DELETE FROM USER") int deleteAll(); } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/entity/UserSecondary.java ================================================ package com.didispace.chapter39.s.entity; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor public class UserSecondary { private Long id; private String name; private Integer age; public UserSecondary(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/mapper/UserMapperSecondary.java ================================================ package com.didispace.chapter39.s.mapper; import com.didispace.chapter39.s.entity.UserSecondary; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; /** * Created by 程序猿DD/翟永超 on 2020/2/28. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserMapperSecondary { @Select("SELECT * FROM USER WHERE NAME = #{name}") UserSecondary findByName(@Param("name") String name); @Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})") int insert(@Param("name") String name, @Param("age") Integer age); @Delete("DELETE FROM USER") int deleteAll(); } ================================================ FILE: 2.x/chapter3-9/src/main/resources/application.properties ================================================ # pring boot 1.x的配置:spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=12345678 spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver # spring boot 1.x的配置:spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=12345678 spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver #mybatis.mapper-locations=classpath:mapper/*.xml ================================================ FILE: 2.x/chapter3-9/src/main/resources/mapper.primary/UserMapper.xml ================================================ INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age}) ================================================ FILE: 2.x/chapter3-9/src/main/resources/mapper.secondary/UserMapper.xml ================================================ INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age}) ================================================ FILE: 2.x/chapter3-9/src/test/java/com/didispace/chapter39/Chapter39ApplicationTests.java ================================================ package com.didispace.chapter39; import com.didispace.chapter39.p.entity.UserPrimary; import com.didispace.chapter39.p.mapper.UserMapperPrimary; import com.didispace.chapter39.s.entity.UserSecondary; import com.didispace.chapter39.s.mapper.UserMapperSecondary; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest @Transactional public class Chapter39ApplicationTests { @Autowired private UserMapperPrimary userMapperPrimary; @Autowired private UserMapperSecondary userMapperSecondary; @Before public void setUp() { // 清空测试表,保证每次结果一样 userMapperPrimary.deleteAll(); userMapperSecondary.deleteAll(); } @Test public void test() throws Exception { // 往Primary数据源插入一条数据 userMapperPrimary.insert("AAA", 20); // 从Primary数据源查询刚才插入的数据,配置正确就可以查询到 UserPrimary userPrimary = userMapperPrimary.findByName("AAA"); Assert.assertEquals(20, userPrimary.getAge().intValue()); // 从Secondary数据源查询刚才插入的数据,配置正确应该是查询不到的 UserSecondary userSecondary = userMapperSecondary.findByName("AAA"); Assert.assertNull(userSecondary); // 往Secondary数据源插入一条数据 userMapperSecondary.insert("BBB", 20); // 从Primary数据源查询刚才插入的数据,配置正确应该是查询不到的 userPrimary = userMapperPrimary.findByName("BBB"); Assert.assertNull(userPrimary); // 从Secondary数据源查询刚才插入的数据,配置正确就可以查询到 userSecondary = userMapperSecondary.findByName("BBB"); Assert.assertEquals(20, userSecondary.getAge().intValue()); } } ================================================ FILE: 2.x/chapter4-1/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter4-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter4-1 0.0.1-SNAPSHOT 使用 Thymeleaf开发Web页面 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter4-1/src/main/java/com/didispace/chapter41/Chapter41Application.java ================================================ package com.didispace.chapter41; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter41Application { public static void main(String[] args) { SpringApplication.run(Chapter41Application.class, args); } } ================================================ FILE: 2.x/chapter4-1/src/main/java/com/didispace/chapter41/HelloController.java ================================================ package com.didispace.chapter41; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HelloController { @GetMapping("/") public String index(ModelMap map) { // 加入一个属性,用来在模板中读取 map.addAttribute("host", "http://blog.didispace.com"); // return模板文件的名称,对应src/main/resources/templates/index.html return "index"; } } ================================================ FILE: 2.x/chapter4-1/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter4-1/src/main/resources/templates/index.html ================================================

Hello World

================================================ FILE: 2.x/chapter4-2/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter4-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter4-2 0.0.1-SNAPSHOT 使用 ECharts 绘制折线图 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter4-2/src/main/java/com/didispace/chapter42/Chapter42Application.java ================================================ package com.didispace.chapter42; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter42Application { public static void main(String[] args) { SpringApplication.run(Chapter42Application.class, args); } } ================================================ FILE: 2.x/chapter4-2/src/main/java/com/didispace/chapter42/HelloController.java ================================================ package com.didispace.chapter42; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HelloController { @GetMapping("/") public String index(ModelMap map) { // return模板文件的名称,对应src/main/resources/templates/index.html return "index"; } } ================================================ FILE: 2.x/chapter4-2/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter4-2/src/main/resources/templates/index.html ================================================ Spring Boot中使用ECharts
================================================ FILE: 2.x/chapter4-3/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter4-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter4-3 0.0.1-SNAPSHOT 文件上传 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter4-3/src/main/java/com/didispace/chapter43/Chapter43Application.java ================================================ package com.didispace.chapter43; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter43Application { public static void main(String[] args) { SpringApplication.run(Chapter43Application.class, args); } } ================================================ FILE: 2.x/chapter4-3/src/main/java/com/didispace/chapter43/UploadController.java ================================================ package com.didispace.chapter43; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Files; @Controller @Slf4j public class UploadController { @Value("${file.upload.path}") private String path; @GetMapping("/") public String uploadPage() { return "upload"; } @PostMapping("/upload") @ResponseBody public String create(@RequestPart MultipartFile file) throws IOException { String fileName = file.getOriginalFilename(); String filePath = path + fileName; File dest = new File(filePath); Files.copy(file.getInputStream(), dest.toPath()); return "Upload file success : " + dest.getAbsolutePath(); } } ================================================ FILE: 2.x/chapter4-3/src/main/resources/application.properties ================================================ spring.servlet.multipart.max-file-size=2MB spring.servlet.multipart.max-request-size=2MB file.upload.path=/Users/zhaiyongchao/ ================================================ FILE: 2.x/chapter4-3/src/main/resources/templates/upload.html ================================================ 文件上传页面

文件上传页面

选择要上传的文件:

================================================ FILE: 2.x/chapter4-3/src/test/java/FileTest.java ================================================ import com.didispace.chapter43.Chapter43Application; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest(classes = Chapter43Application.class) public class FileTest { @Autowired protected WebApplicationContext context; protected MockMvc mvc; @BeforeEach public void setUp() { mvc = MockMvcBuilders.webAppContextSetup(context).build(); } @Test public void uploadFile() throws Exception { MockMultipartFile file = new MockMultipartFile( "file", "hello.txt", MediaType.TEXT_PLAIN_VALUE, "Hello, World!".getBytes() ); final MvcResult result = mvc.perform( MockMvcRequestBuilders .multipart("/upload") .file(file)) .andDo(print()) .andExpect(status().isOk()) .andReturn(); } } ================================================ FILE: 2.x/chapter4-4/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter4-4/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter4-4 0.0.1-SNAPSHOT 多文件上传 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter4-4/src/main/java/com/didispace/chapter44/Chapter44Application.java ================================================ package com.didispace.chapter44; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter44Application { public static void main(String[] args) { SpringApplication.run(Chapter44Application.class, args); } } ================================================ FILE: 2.x/chapter4-4/src/main/java/com/didispace/chapter44/UploadController.java ================================================ package com.didispace.chapter44; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Files; @Controller @Slf4j public class UploadController { @Value("${file.upload.path}") private String path; @GetMapping("/") public String uploadPage() { return "upload"; } @PostMapping("/upload") @ResponseBody public String create(@RequestPart MultipartFile[] files) throws IOException { StringBuffer message = new StringBuffer(); for (MultipartFile file : files) { String fileName = file.getOriginalFilename(); String filePath = path + fileName; File dest = new File(filePath); Files.copy(file.getInputStream(), dest.toPath()); message.append("Upload file success : " + dest.getAbsolutePath()).append("
"); } return message.toString(); } } ================================================ FILE: 2.x/chapter4-4/src/main/resources/application.properties ================================================ spring.servlet.multipart.max-file-size=2MB spring.servlet.multipart.max-request-size=2MB file.upload.path=/Users/didi/ ================================================ FILE: 2.x/chapter4-4/src/main/resources/templates/upload.html ================================================ 文件上传页面

文件上传页面

文件1:
文件2:

================================================ FILE: 2.x/chapter4-4/src/test/java/FileTest.java ================================================ import org.junit.jupiter.api.Test; public class FileTest { @Test public void uploadFile() throws Exception { } } ================================================ FILE: 2.x/chapter4-5/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter4-5 0.0.1-SNAPSHOT Spring Security快速入门 UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 2.x/chapter4-5/src/main/java/com/didispace/chapter45/Application.java ================================================ package com.didispace.chapter45; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ================================================ FILE: 2.x/chapter4-5/src/main/java/com/didispace/chapter45/HelloController.java ================================================ package com.didispace.chapter45; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com * */ @Controller public class HelloController { @RequestMapping("/") public String index() { return "index"; } @RequestMapping("/hello") public String hello() { return "hello"; } @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } } ================================================ FILE: 2.x/chapter4-5/src/main/java/com/didispace/chapter45/WebSecurityConfig.java ================================================ package com.didispace.chapter45; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } } ================================================ FILE: 2.x/chapter4-5/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter4-5/src/main/resources/templates/hello.html ================================================ Hello World!

Hello [[${#httpServletRequest.remoteUser}]]!

================================================ FILE: 2.x/chapter4-5/src/main/resources/templates/index.html ================================================ Spring Security入门

欢迎使用Spring Security!

点击 这里 打个招呼吧

================================================ FILE: 2.x/chapter4-5/src/main/resources/templates/login.html ================================================ Spring Security Example
用户名或密码错
您已注销成功
================================================ FILE: 2.x/chapter5-1/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter5-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter5-1 0.0.1-SNAPSHOT 使用进程内缓存 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-cache org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter5-1/src/main/java/com/didispace/chapter51/Chapter51Application.java ================================================ package com.didispace.chapter51; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @EnableCaching @SpringBootApplication public class Chapter51Application { public static void main(String[] args) { SpringApplication.run(Chapter51Application.class, args); } } ================================================ FILE: 2.x/chapter5-1/src/main/java/com/didispace/chapter51/User.java ================================================ package com.didispace.chapter51; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity @Data @NoArgsConstructor public class User { @Id @GeneratedValue private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter5-1/src/main/java/com/didispace/chapter51/UserRepository.java ================================================ package com.didispace.chapter51; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/7/13. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository { @Cacheable User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name); } ================================================ FILE: 2.x/chapter5-1/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create-drop ================================================ FILE: 2.x/chapter5-1/src/test/java/com/didispace/chapter51/Chapter51ApplicationTests.java ================================================ package com.didispace.chapter51; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cache.CacheManager; import org.springframework.test.context.junit4.SpringRunner; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter51ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private CacheManager cacheManager; @Test public void test() throws Exception { // 创建1条记录 userRepository.save(new User("AAA", 10)); User u1 = userRepository.findByName("AAA"); System.out.println("第一次查询:" + u1.getAge()); User u2 = userRepository.findByName("AAA"); System.out.println("第二次查询:" + u2.getAge()); } } ================================================ FILE: 2.x/chapter5-2/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter5-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter5-2 0.0.1-SNAPSHOT 使用进程内缓存 EhCache 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-cache net.sf.ehcache ehcache org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter5-2/src/main/java/com/didispace/chapter52/Chapter52Application.java ================================================ package com.didispace.chapter52; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @EnableCaching @SpringBootApplication public class Chapter52Application { public static void main(String[] args) { SpringApplication.run(Chapter52Application.class, args); } } ================================================ FILE: 2.x/chapter5-2/src/main/java/com/didispace/chapter52/User.java ================================================ package com.didispace.chapter52; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity @Data @NoArgsConstructor public class User { @Id @GeneratedValue private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter5-2/src/main/java/com/didispace/chapter52/UserRepository.java ================================================ package com.didispace.chapter52; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/7/14. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository { @Cacheable User findByName(String name); } ================================================ FILE: 2.x/chapter5-2/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create-drop ================================================ FILE: 2.x/chapter5-2/src/main/resources/ehcache.xml ================================================ ================================================ FILE: 2.x/chapter5-2/src/test/java/com/didispace/chapter52/Chapter52ApplicationTests.java ================================================ package com.didispace.chapter52; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cache.CacheManager; import org.springframework.test.context.junit4.SpringRunner; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter52ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private CacheManager cacheManager; @Test public void test() throws Exception { System.out.println("CacheManager type : " + cacheManager.getClass()); // 创建1条记录 userRepository.save(new User("AAA", 10)); User u1 = userRepository.findByName("AAA"); System.out.println("第一次查询:" + u1.getAge()); User u2 = userRepository.findByName("AAA"); System.out.println("第二次查询:" + u2.getAge()); } } ================================================ FILE: 2.x/chapter5-3/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter5-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter5-3 0.0.1-SNAPSHOT 使用EhCache缓存集群 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-cache net.sf.ehcache ehcache org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter5-3/src/main/java/com/didispace/chapter53/Chapter53Application.java ================================================ package com.didispace.chapter53; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.rmi.registry.LocateRegistry; @EnableCaching @SpringBootApplication public class Chapter53Application { public static void main(String[] args) throws Exception { // LocateRegistry.createRegistry(Integer.valueOf(System.getProperty("rmi.port"))); SpringApplication.run(Chapter53Application.class, args); } @RestController static class HelloController { @Autowired private UserRepository userRepository; @GetMapping("/create") public void create() { userRepository.save(new User("AAA", 10)); } @GetMapping("/update") public User update() { User u1 = userRepository.findByName("AAA"); u1.setAge(20); u1 = userRepository.save(u1); return u1; } @GetMapping("/find") public User find() { User u1 = userRepository.findByName("AAA"); System.out.println("查询AAA用户:" + u1.getAge()); return u1; } } } ================================================ FILE: 2.x/chapter5-3/src/main/java/com/didispace/chapter53/User.java ================================================ package com.didispace.chapter53; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.io.Serializable; @Entity @Data @NoArgsConstructor public class User implements Serializable { @Id @GeneratedValue private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter5-3/src/main/java/com/didispace/chapter53/UserRepository.java ================================================ package com.didispace.chapter53; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/7/16. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository { @Cacheable User findByName(String name); } ================================================ FILE: 2.x/chapter5-3/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create #logging.level.net.sf.ehcache=debug # 不同实例的配置 #spring.cache.ehcache.config=classpath:ehcache-1.xml #spring.cache.ehcache.config=classpath:ehcache-2.xml # 用不同命令启动不同实例 #-Dserver.port=8001 -Dspring.cache.ehcache.config=classpath:ehcache-1.xml #-Dserver.port=8002 -Dspring.cache.ehcache.config=classpath:ehcache-2.xml ================================================ FILE: 2.x/chapter5-3/src/main/resources/ehcache-1.xml ================================================ ================================================ FILE: 2.x/chapter5-3/src/main/resources/ehcache-2.xml ================================================ ================================================ FILE: 2.x/chapter5-3/src/test/java/com/didispace/chapter53/Chapter53ApplicationTests.java ================================================ package com.didispace.chapter53; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cache.CacheManager; import org.springframework.test.context.junit4.SpringRunner; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter53ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private CacheManager cacheManager; @Test public void test() throws Exception { System.out.println("CacheManager type : " + cacheManager.getClass()); // 创建1条记录 userRepository.save(new User("AAA", 10)); User u1 = userRepository.findByName("AAA"); System.out.println("第一次查询:" + u1.getAge()); User u2 = userRepository.findByName("AAA"); System.out.println("第二次查询:" + u2.getAge()); } } ================================================ FILE: 2.x/chapter5-4/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter5-4/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE com.didispace chapter5-4 0.0.1-SNAPSHOT 使用集中式缓存Redis 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 org.springframework.boot spring-boot-starter-actuator mysql mysql-connector-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter5-4/src/main/java/com/didispace/chapter54/Chapter54Application.java ================================================ package com.didispace.chapter54; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @EnableCaching @SpringBootApplication public class Chapter54Application { public static void main(String[] args) { SpringApplication.run(Chapter54Application.class, args); } } ================================================ FILE: 2.x/chapter5-4/src/main/java/com/didispace/chapter54/User.java ================================================ package com.didispace.chapter54; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.io.Serializable; @Entity @Data @NoArgsConstructor public class User implements Serializable { @Id @GeneratedValue private Long id; private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter5-4/src/main/java/com/didispace/chapter54/UserRepository.java ================================================ package com.didispace.chapter54; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2020/7/26. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository { @Cacheable User findByName(String name); User findByNameAndAge(String name, Integer age); @Query("from User u where u.name=:name") User findUser(@Param("name") String name); } ================================================ FILE: 2.x/chapter5-4/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=12345678 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create-drop spring.redis.host=localhost spring.redis.port=6379 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.min-idle=0 spring.redis.lettuce.shutdown-timeout=100ms ================================================ FILE: 2.x/chapter5-4/src/test/java/com/didispace/chapter54/Chapter54ApplicationTests.java ================================================ package com.didispace.chapter54; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cache.CacheManager; import org.springframework.test.context.junit4.SpringRunner; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter54ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private CacheManager cacheManager; @Test public void test() throws Exception { System.out.println("CacheManager type : " + cacheManager.getClass()); // 创建1条记录 userRepository.save(new User("AAA", 10)); User u1 = userRepository.findByName("AAA"); System.out.println("第一次查询:" + u1.getAge()); User u2 = userRepository.findByName("AAA"); System.out.println("第二次查询:" + u2.getAge()); } } ================================================ FILE: 2.x/chapter5-5/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: 2.x/chapter5-5/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter5-5 0.0.1-SNAPSHOT 使用Redis的发布订阅 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 org.springframework.boot spring-boot-starter-actuator org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter5-5/src/main/java/com/didispace/chapter55/Chapter55Application.java ================================================ package com.didispace.chapter55; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.nio.charset.StandardCharsets; @SpringBootApplication public class Chapter55Application { private static String CHANNEL = "didispace"; public static void main(String[] args) { SpringApplication.run(Chapter55Application.class, args); } @RestController static class RedisController { private RedisTemplate redisTemplate; public RedisController(RedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } @GetMapping("/publish") public void publish(@RequestParam String message) { // 发送消息 redisTemplate.convertAndSend(CHANNEL, message); } } @Slf4j @Service static class MessageSubscriber { public MessageSubscriber(RedisTemplate redisTemplate) { RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection(); redisConnection.subscribe(new MessageListener() { @Override public void onMessage(Message message, byte[] bytes) { // 收到消息的处理逻辑 log.info("Receive message : " + message); } }, CHANNEL.getBytes(StandardCharsets.UTF_8)); } } } ================================================ FILE: 2.x/chapter5-5/src/main/resources/application.properties ================================================ spring.redis.host=localhost spring.redis.port=6379 spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.min-idle=0 spring.redis.lettuce.shutdown-timeout=100ms ================================================ FILE: 2.x/chapter6-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.1 com.didispace chapter6-1 0.0.1-SNAPSHOT 使用MongoDB 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-mongodb org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter6-1/src/main/java/com/didispace/chapter61/Chapter61Application.java ================================================ package com.didispace.chapter61; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter61Application { public static void main(String[] args) { SpringApplication.run(Chapter61Application.class, args); } } ================================================ FILE: 2.x/chapter6-1/src/main/java/com/didispace/chapter61/User.java ================================================ package com.didispace.chapter61; import lombok.AllArgsConstructor; import lombok.Data; import org.springframework.data.annotation.Id; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ @Data @AllArgsConstructor public class User { @Id private Long id; private String username; private Integer age; } ================================================ FILE: 2.x/chapter6-1/src/main/java/com/didispace/chapter61/UserRepository.java ================================================ package com.didispace.chapter61; import org.springframework.data.mongodb.repository.MongoRepository; /** * @author 程序猿DD * @version 1.0.0 * @blog http://blog.didispace.com */ public interface UserRepository extends MongoRepository { User findByUsername(String username); } ================================================ FILE: 2.x/chapter6-1/src/main/resources/application.properties ================================================ spring.data.mongodb.uri=mongodb://localhost:27017/test ================================================ FILE: 2.x/chapter6-1/src/test/java/com/didispace/chapter61/ApplicationTests.java ================================================ package com.didispace.chapter61; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(classes = Chapter61Application.class) public class ApplicationTests { @Autowired private UserRepository userRepository; @Test public void test() throws Exception { userRepository.deleteAll(); // 创建三个User,并验证User总数 userRepository.save(new User(1L, "didi", 30)); userRepository.save(new User(2L, "mama", 40)); userRepository.save(new User(3L, "kaka", 50)); Assertions.assertEquals(3, userRepository.findAll().size()); // 删除一个User,再验证User总数 User u = userRepository.findById(1L).get(); userRepository.delete(u); Assertions.assertEquals(2, userRepository.findAll().size()); // 删除一个User,再验证User总数 u = userRepository.findByUsername("mama"); userRepository.delete(u); Assertions.assertEquals(1, userRepository.findAll().size()); } } ================================================ FILE: 2.x/chapter6-2/pom.xml ================================================ 4.0.0 com.didispace chapter6-2 1.0.0 jar 使用轻量级树状存储 LDAP org.springframework.boot spring-boot-starter-parent 2.5.1 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-ldap org.projectlombok lombok provided com.unboundid unboundid-ldapsdk test org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter6-2/src/main/java/com/didispace/chapter62/Chapter62Application.java ================================================ package com.didispace.chapter62; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter62Application { public static void main(String[] args) { SpringApplication.run(Chapter62Application.class, args); } } ================================================ FILE: 2.x/chapter6-2/src/main/java/com/didispace/chapter62/Person.java ================================================ package com.didispace.chapter62; import lombok.Data; import org.springframework.ldap.odm.annotations.*; import javax.naming.Name; @Entry(base = "ou=people,dc=didispace,dc=com", objectClasses = "inetOrgPerson") @Data public class Person { @Id private Name id; @DnAttribute(value = "uid", index = 3) private String uid; @Attribute(name = "cn") private String commonName; @Attribute(name = "sn") private String userName; private String userPassword; } ================================================ FILE: 2.x/chapter6-2/src/main/java/com/didispace/chapter62/PersonRepository.java ================================================ package com.didispace.chapter62; import org.springframework.data.repository.CrudRepository; import javax.naming.Name; public interface PersonRepository extends CrudRepository { } ================================================ FILE: 2.x/chapter6-2/src/main/resources/application.properties ================================================ #spring.ldap.urls=ldap://localhost:1235 #spring.ldap.base=dc=didispace,dc=com #spring.ldap.username=didispace #spring.ldap.password=123456 ================================================ FILE: 2.x/chapter6-2/src/test/java/com/didispace/chapter62/ApplicationTests.java ================================================ package com.didispace.chapter62; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @Slf4j @SpringBootTest public class ApplicationTests { @Autowired private PersonRepository personRepository; @Test public void findAll() { personRepository.findAll().forEach(p -> { System.out.println(p); }); } @Test public void save() { Person person = new Person(); person.setUid("uid:1"); person.setUserName("AAA"); person.setCommonName("aaa"); person.setUserPassword("123456"); personRepository.save(person); personRepository.findAll().forEach(p -> { System.out.println(p); }); } } ================================================ FILE: 2.x/chapter6-2/src/test/resources/application.properties ================================================ spring.ldap.embedded.ldif=classpath:ldap-server.ldif spring.ldap.embedded.base-dn=dc=didispace,dc=com ================================================ FILE: 2.x/chapter6-2/src/test/resources/ldap-server.ldif ================================================ dn: dc=didispace,dc=com objectClass: top objectClass: domain objectclass: extensibleObject dc: didispace dn: ou=people,dc=didispace,dc=com objectclass: top objectclass: organizationalUnit ou: people dn: uid=ben,ou=people,dc=didispace,dc=com objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: didi sn: zhaiyongchao uid: didi userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ= ================================================ FILE: 2.x/chapter6-3/pom.xml ================================================ 4.0.0 com.didispace chapter6-3 1.0.0 jar 使用时序数据库InfluxDB org.springframework.boot spring-boot-starter-parent 2.5.1 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.influxdb influxdb-java org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter6-3/src/main/java/com/didispace/chapter63/Chapter63Application.java ================================================ package com.didispace.chapter63; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @SpringBootApplication public class Chapter63Application { public static void main(String[] args) { SpringApplication.run(Chapter63Application.class, args); } } ================================================ FILE: 2.x/chapter6-3/src/main/java/com/didispace/chapter63/Monitor.java ================================================ package com.didispace.chapter63; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.influxdb.InfluxDB; import org.influxdb.dto.Point; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.util.Random; import java.util.concurrent.TimeUnit; /** * Created by 程序猿DD on 2021/8/2. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ @Service @AllArgsConstructor @Slf4j public class Monitor { private InfluxDB influxDB; @Scheduled(fixedRate = 5000) public void writeQPS() { // 模拟要上报的统计数据 int count = (int) (Math.random() * 100); Point point = Point.measurement("ApiQPS") // ApiQPS表 .tag("url", "/hello") // url字段 .addField("count", count) // 统计数据 .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS) // 时间 .build(); // 往test库写数据 influxDB.write("test", "autogen", point); log.info("上报统计数据:" + count); } } ================================================ FILE: 2.x/chapter6-3/src/main/resources/application.properties ================================================ spring.influx.url=http://localhost:8086 spring.influx.user=admin spring.influx.password= ================================================ FILE: 2.x/chapter6-3/src/test/java/com/didispace/chapter63/ApplicationTests.java ================================================ package com.didispace.chapter63; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @Slf4j @SpringBootTest public class ApplicationTests { @Test public void findAll() { } @Test public void save() { } } ================================================ FILE: 2.x/chapter6-4/pom.xml ================================================ 4.0.0 com.didispace chapter6-4 1.0.0 jar 使用PostgreSQL数据库 org.springframework.boot spring-boot-starter-parent 2.5.1 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.postgresql postgresql runtime org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter6-4/src/main/java/com/didispace/chapter64/Chapter64Application.java ================================================ package com.didispace.chapter64; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication public class Chapter64Application { public static void main(String[] args) { SpringApplication.run(Chapter64Application.class, args); } } ================================================ FILE: 2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfo.java ================================================ package com.didispace.chapter64; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity @Data @NoArgsConstructor public class UserInfo { @Id @GeneratedValue private Long id; private String name; private Integer age; public UserInfo(String name, Integer age) { this.name = name; this.age = age; } } ================================================ FILE: 2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfoRepository.java ================================================ package com.didispace.chapter64; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; /** * Created by 程序猿DD/翟永超 on 2021/10/08. *

* Blog: http://blog.didispace.com/ * Github: https://github.com/dyc87112/ */ public interface UserInfoRepository extends JpaRepository { UserInfo findByName(String name); UserInfo findByNameAndAge(String name, Integer age); @Query("from UserInfo u where u.name=:name") UserInfo findUser(@Param("name") String name); } ================================================ FILE: 2.x/chapter6-4/src/main/resources/application.properties ================================================ spring.datasource.url=jdbc:postgresql://localhost:5432/test spring.datasource.username=postgres spring.datasource.password=123456 spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.properties.hibernate.hbm2ddl.auto=create ================================================ FILE: 2.x/chapter6-4/src/test/java/com/didispace/chapter64/ApplicationTests.java ================================================ package com.didispace.chapter64; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @Slf4j @SpringBootTest public class ApplicationTests { @Autowired private UserInfoRepository userRepository; @Test public void test() throws Exception { // 创建10条记录 userRepository.save(new UserInfo("AAA", 10)); userRepository.save(new UserInfo("BBB", 20)); userRepository.save(new UserInfo("CCC", 30)); userRepository.save(new UserInfo("DDD", 40)); userRepository.save(new UserInfo("EEE", 50)); userRepository.save(new UserInfo("FFF", 60)); userRepository.save(new UserInfo("GGG", 70)); userRepository.save(new UserInfo("HHH", 80)); userRepository.save(new UserInfo("III", 90)); userRepository.save(new UserInfo("JJJ", 100)); // 测试findAll, 查询所有记录 Assertions.assertEquals(10, userRepository.findAll().size()); // 测试findByName, 查询姓名为FFF的User Assertions.assertEquals(60, userRepository.findByName("FFF").getAge().longValue()); // 测试findUser, 查询姓名为FFF的User Assertions.assertEquals(60, userRepository.findUser("FFF").getAge().longValue()); // 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User Assertions.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName()); // 测试删除姓名为AAA的User userRepository.delete(userRepository.findByName("AAA")); // 测试findAll, 查询所有记录, 验证上面的删除是否成功 Assertions.assertEquals(9, userRepository.findAll().size()); } } ================================================ FILE: 2.x/chapter7-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-1 0.0.1-SNAPSHOT 使用@Scheduled实现定时任务 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-1/src/main/java/com/didispace/chapter71/Chapter71Application.java ================================================ package com.didispace.chapter71; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @SpringBootApplication public class Chapter71Application { public static void main(String[] args) { SpringApplication.run(Chapter71Application.class, args); } } ================================================ FILE: 2.x/chapter7-1/src/main/java/com/didispace/chapter71/ScheduledTasks.java ================================================ package com.didispace.chapter71; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @Slf4j @Component @AllArgsConstructor public class ScheduledTasks { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(fixedRate = 5000) public void reportCurrentTime() { log.info("现在时间:" + dateFormat.format(new Date())); } } ================================================ FILE: 2.x/chapter7-1/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter7-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-2 0.0.1-SNAPSHOT 使用Elastic Job实现定时任务 1.8 org.apache.shardingsphere.elasticjob elasticjob-lite-spring-boot-starter 3.0.0 org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-2/src/main/java/com/didispace/chapter72/Chapter72Application.java ================================================ package com.didispace.chapter72; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter72Application { public static void main(String[] args) { SpringApplication.run(Chapter72Application.class, args); } } ================================================ FILE: 2.x/chapter7-2/src/main/java/com/didispace/chapter72/MySimpleJob.java ================================================ package com.didispace.chapter72; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.elasticjob.api.ShardingContext; import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob; import org.springframework.stereotype.Service; @Slf4j @Service public class MySimpleJob implements SimpleJob { @Override public void execute(ShardingContext context) { log.info("MySimpleJob start : didispace.com {}", System.currentTimeMillis()); } } ================================================ FILE: 2.x/chapter7-2/src/main/resources/application.properties ================================================ elasticjob.reg-center.server-lists=localhost:2181 elasticjob.reg-center.namespace=didispace elasticjob.jobs.my-simple-job.elastic-job-class=com.didispace.chapter72.MySimpleJob elasticjob.jobs.my-simple-job.cron=0/5 * * * * ? elasticjob.jobs.my-simple-job.sharding-total-count=1 ================================================ FILE: 2.x/chapter7-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-3 0.0.1-SNAPSHOT 使用Elastic Job的分片配置 1.8 org.apache.shardingsphere.elasticjob elasticjob-lite-spring-boot-starter 3.0.0 org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-3/src/main/java/com/didispace/chapter73/Chapter73Application.java ================================================ package com.didispace.chapter73; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter73Application { public static void main(String[] args) { SpringApplication.run(Chapter73Application.class, args); } } ================================================ FILE: 2.x/chapter7-3/src/main/java/com/didispace/chapter73/MyShardingJob.java ================================================ package com.didispace.chapter73; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.elasticjob.api.ShardingContext; import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob; import org.springframework.stereotype.Service; @Slf4j @Service public class MyShardingJob implements SimpleJob { @Override public void execute(ShardingContext context) { // sharding-total-count=3,所以任务被分为三个分片 switch (context.getShardingItem()) { case 0: log.info("分片1:执行任务"); break; case 1: log.info("分片2:执行任务"); break; case 2: log.info("分片3:执行任务"); break; } } } ================================================ FILE: 2.x/chapter7-3/src/main/resources/application.properties ================================================ elasticjob.reg-center.server-lists=localhost:2181 elasticjob.reg-center.namespace=didispace elasticjob.jobs.my-sharding-job.elastic-job-class=com.didispace.chapter73.MyShardingJob elasticjob.jobs.my-sharding-job.cron=0/5 * * * * ? elasticjob.jobs.my-sharding-job.sharding-total-count=3 ================================================ FILE: 2.x/chapter7-4/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-4 0.0.1-SNAPSHOT Elastic Job的错误处理策略 1.8 org.apache.shardingsphere.elasticjob elasticjob-lite-spring-boot-starter 3.0.0 org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-4/src/main/java/com/didispace/chapter74/Chapter74Application.java ================================================ package com.didispace.chapter74; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Chapter74Application { public static void main(String[] args) { SpringApplication.run(Chapter74Application.class, args); } } ================================================ FILE: 2.x/chapter7-4/src/main/java/com/didispace/chapter74/MySimpleJob.java ================================================ package com.didispace.chapter74; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.elasticjob.api.ShardingContext; import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob; import org.springframework.stereotype.Service; @Slf4j @Service public class MySimpleJob implements SimpleJob { @Override public void execute(ShardingContext context) { log.info("MySimpleJob start : didispace.com {}", System.currentTimeMillis()); } } ================================================ FILE: 2.x/chapter7-4/src/main/resources/application.properties ================================================ spring.application.name=chapter74 elasticjob.reg-center.server-lists=localhost:2181 elasticjob.reg-center.namespace=${spring.application.name} elasticjob.jobs.my-simple-job.elastic-job-class=com.didispace.chapter74.MySimpleJob elasticjob.jobs.my-simple-job.cron=0/5 * * * * ? elasticjob.jobs.my-simple-job.sharding-total-count=1 ================================================ FILE: 2.x/chapter7-5/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-5 0.0.1-SNAPSHOT 使用@Async实现异步任务 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-5/src/main/java/com/didispace/chapter75/AsyncTasks.java ================================================ package com.didispace.chapter75; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.Random; import java.util.concurrent.CompletableFuture; @Slf4j @Component public class AsyncTasks { public static Random random = new Random(); @Async public CompletableFuture doTaskOne() throws Exception { log.info("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务一,耗时:" + (end - start) + "毫秒"); return CompletableFuture.completedFuture("任务一完成"); } @Async public CompletableFuture doTaskTwo() throws Exception { log.info("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务二,耗时:" + (end - start) + "毫秒"); return CompletableFuture.completedFuture("任务二完成"); } @Async public CompletableFuture doTaskThree() throws Exception { log.info("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务三,耗时:" + (end - start) + "毫秒"); return CompletableFuture.completedFuture("任务三完成"); } } ================================================ FILE: 2.x/chapter7-5/src/main/java/com/didispace/chapter75/Chapter75Application.java ================================================ package com.didispace.chapter75; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; @EnableAsync @SpringBootApplication public class Chapter75Application { public static void main(String[] args) { SpringApplication.run(Chapter75Application.class, args); } } ================================================ FILE: 2.x/chapter7-5/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter7-5/src/test/java/com/didispace/chapter75/Chapter75ApplicationTests.java ================================================ package com.didispace.chapter75; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @Slf4j @SpringBootTest public class Chapter75ApplicationTests { @Autowired private AsyncTasks asyncTasks; @Test public void test() throws Exception { long start = System.currentTimeMillis(); CompletableFuture task1 = asyncTasks.doTaskOne(); CompletableFuture task2 = asyncTasks.doTaskTwo(); CompletableFuture task3 = asyncTasks.doTaskThree(); CompletableFuture.allOf(task1, task2, task3).join(); long end = System.currentTimeMillis(); log.info("任务全部完成,总耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 2.x/chapter7-6/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-6 0.0.1-SNAPSHOT @Async异步任务的线程池配置 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-6/src/main/java/com/didispace/chapter76/AsyncTasks.java ================================================ package com.didispace.chapter76; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @Slf4j @Component public class AsyncTasks { public static Random random = new Random(); @Async public CompletableFuture doTaskOne() throws Exception { log.info("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务一,耗时:" + (end - start) + "毫秒"); return CompletableFuture.completedFuture("任务一完成"); } @Async public CompletableFuture doTaskTwo() throws Exception { log.info("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务二,耗时:" + (end - start) + "毫秒"); return CompletableFuture.completedFuture("任务二完成"); } @Async public CompletableFuture doTaskThree() throws Exception { log.info("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务三,耗时:" + (end - start) + "毫秒"); return CompletableFuture.completedFuture("任务三完成"); } } ================================================ FILE: 2.x/chapter7-6/src/main/java/com/didispace/chapter76/Chapter76Application.java ================================================ package com.didispace.chapter76; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; @EnableAsync @SpringBootApplication public class Chapter76Application { public static void main(String[] args) { SpringApplication.run(Chapter76Application.class, args); } } ================================================ FILE: 2.x/chapter7-6/src/main/resources/application.properties ================================================ spring.task.execution.pool.core-size=2 spring.task.execution.pool.max-size=5 spring.task.execution.pool.queue-capacity=10 spring.task.execution.pool.keep-alive=60s spring.task.execution.pool.allow-core-thread-timeout=true spring.task.execution.thread-name-prefix=task- spring.task.execution.shutdown.await-termination=false spring.task.execution.shutdown.await-termination-period=30s ================================================ FILE: 2.x/chapter7-6/src/test/java/com/didispace/chapter76/Chapter76ApplicationTests.java ================================================ package com.didispace.chapter76; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.CompletableFuture; @Slf4j @SpringBootTest public class Chapter76ApplicationTests { @Autowired private AsyncTasks asyncTasks; @Test public void test1() throws Exception { long start = System.currentTimeMillis(); CompletableFuture task1 = asyncTasks.doTaskOne(); CompletableFuture task2 = asyncTasks.doTaskTwo(); CompletableFuture task3 = asyncTasks.doTaskThree(); CompletableFuture.allOf(task1, task2, task3).join(); long end = System.currentTimeMillis(); log.info("任务全部完成,总耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 2.x/chapter7-7/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-7 0.0.1-SNAPSHOT 如何隔离@Async异步任务的线程池 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-7/src/main/java/com/didispace/chapter77/AsyncTasks.java ================================================ package com.didispace.chapter77; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.Random; import java.util.concurrent.CompletableFuture; @Slf4j @Component public class AsyncTasks { public static Random random = new Random(); @Async("taskExecutor1") public CompletableFuture doTaskOne(String taskNo) throws Exception { log.info("开始任务:{}", taskNo); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start); return CompletableFuture.completedFuture("任务完成"); } @Async("taskExecutor2") public CompletableFuture doTaskTwo(String taskNo) throws Exception { log.info("开始任务:{}", taskNo); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start); return CompletableFuture.completedFuture("任务完成"); } } ================================================ FILE: 2.x/chapter7-7/src/main/java/com/didispace/chapter77/Chapter77Application.java ================================================ package com.didispace.chapter77; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; @EnableAsync @SpringBootApplication public class Chapter77Application { public static void main(String[] args) { SpringApplication.run(Chapter77Application.class, args); } @EnableAsync @Configuration class TaskPoolConfig { @Bean public Executor taskExecutor1() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); executor.setMaxPoolSize(2); executor.setQueueCapacity(10); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("executor-1-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } @Bean public Executor taskExecutor2() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); executor.setMaxPoolSize(2); executor.setQueueCapacity(10); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("executor-2-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } } } ================================================ FILE: 2.x/chapter7-7/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter7-7/src/test/java/com/didispace/chapter77/Chapter77ApplicationTests.java ================================================ package com.didispace.chapter77; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @Slf4j @SpringBootTest public class Chapter77ApplicationTests { @Autowired private AsyncTasks asyncTasks; @Test public void test() throws Exception { long start = System.currentTimeMillis(); // 线程池1 CompletableFuture task1 = asyncTasks.doTaskOne("1"); CompletableFuture task2 = asyncTasks.doTaskOne("2"); CompletableFuture task3 = asyncTasks.doTaskOne("3"); // 线程池2 CompletableFuture task4 = asyncTasks.doTaskTwo("4"); CompletableFuture task5 = asyncTasks.doTaskTwo("5"); CompletableFuture task6 = asyncTasks.doTaskTwo("6"); // 一起执行 CompletableFuture.allOf(task1, task2, task3, task4, task5, task6).join(); long end = System.currentTimeMillis(); log.info("任务全部完成,总耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 2.x/chapter7-8/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter7-8 0.0.1-SNAPSHOT 为@Async异步任务线程池配置拒绝策略 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2.x/chapter7-8/src/main/java/com/didispace/chapter78/AsyncTasks.java ================================================ package com.didispace.chapter78; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.Random; import java.util.concurrent.CompletableFuture; @Slf4j @Component public class AsyncTasks { public static Random random = new Random(); @Async("taskExecutor1") public CompletableFuture doTaskOne(String taskNo) throws Exception { log.info("开始任务:{}", taskNo); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); log.info("完成任务:{},耗时:{} 毫秒", taskNo, end - start); return CompletableFuture.completedFuture("任务完成"); } } ================================================ FILE: 2.x/chapter7-8/src/main/java/com/didispace/chapter78/Chapter78Application.java ================================================ package com.didispace.chapter78; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @EnableAsync @SpringBootApplication public class Chapter78Application { public static void main(String[] args) { SpringApplication.run(Chapter78Application.class, args); } @EnableAsync @Configuration class TaskPoolConfig { @Bean public Executor taskExecutor1() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); executor.setMaxPoolSize(2); executor.setQueueCapacity(2); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("executor-1-"); /**配置拒绝策略**/ // AbortPolicy策略:默认策略,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); // DiscardPolicy策略:如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); // DiscardOldestPolicy策略:如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列。 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); // CallerRunsPolicy策略:如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 自定义策略 // executor.setRejectedExecutionHandler(new RejectedExecutionHandler() { // @Override // public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // // } // }); return executor; } } } ================================================ FILE: 2.x/chapter7-8/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter7-8/src/test/java/com/didispace/chapter78/Chapter78ApplicationTests.java ================================================ package com.didispace.chapter78; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @Slf4j @SpringBootTest public class Chapter78ApplicationTests { @Autowired private AsyncTasks asyncTasks; @Test public void test() throws Exception { // 线程池配置:core-2,max-2,queue=2,可以容纳4个任务提交 long start = System.currentTimeMillis(); // 线程池1 CompletableFuture task1 = asyncTasks.doTaskOne("1"); CompletableFuture task2 = asyncTasks.doTaskOne("2"); CompletableFuture task3 = asyncTasks.doTaskOne("3"); CompletableFuture task4 = asyncTasks.doTaskOne("4"); // 一起执行 CompletableFuture.allOf(task1, task2, task3, task4).join(); long end = System.currentTimeMillis(); log.info("任务全部完成,总耗时:" + (end - start) + "毫秒"); } @Test public void test2() throws Exception { // 线程池配置:core-2,max-2,queue=2,同时有5个任务,出现下面异常: // org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor@59901c4d[Running, pool size = 2, // active threads = 0, queued tasks = 2, completed tasks = 4]] did not accept task: java.util.concurrent.CompletableFuture$AsyncSupply@408e96d9 long start = System.currentTimeMillis(); // 线程池1 CompletableFuture task1 = asyncTasks.doTaskOne("1"); CompletableFuture task2 = asyncTasks.doTaskOne("2"); CompletableFuture task3 = asyncTasks.doTaskOne("3"); CompletableFuture task4 = asyncTasks.doTaskOne("4"); CompletableFuture task5 = asyncTasks.doTaskOne("5"); // 一起执行 CompletableFuture.allOf(task1, task2, task3, task4, task5).join(); long end = System.currentTimeMillis(); log.info("任务全部完成,总耗时:" + (end - start) + "毫秒"); } } ================================================ FILE: 2.x/chapter8-1/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.1 com.didispace chapter8-1 0.0.1-SNAPSHOT 默认日志管理与Logback配置详解 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.projectlombok lombok provided org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 2.x/chapter8-1/src/main/java/com/didispace/chapter81/Chapter81Application.java ================================================ package com.didispace.chapter81; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 程序猿DD * @version 1.0.0 * @blog https://blog.didispace.com */ @Slf4j @SpringBootApplication public class Chapter81Application { public static void main(String[] args) { SpringApplication.run(Chapter81Application.class, args); log.error("Hello World"); log.warn("Hello World"); log.info("Hello World"); log.debug("Hello World"); log.trace("Hello World"); } } ================================================ FILE: 2.x/chapter8-1/src/main/resources/application.properties ================================================ debug=true spring.output.ansi.enabled=detect logging.file.name=run.log logging.file.path=./ logging.level.com.didispace=debug logging.logback.rollingpolicy.clean-history-on-start=false logging.logback.rollingpolicy.file-name-pattern= logging.logback.rollingpolicy.max-history=7 logging.logback.rollingpolicy.max-file-size=10MB logging.logback.rollingpolicy.total-size-cap=0B ================================================ FILE: 2.x/chapter8-2/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.6.1 com.didispace chapter8-2 0.0.1-SNAPSHOT 使用log4j2记录日志 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-log4j2 org.springframework.boot spring-boot-starter-test test org.projectlombok lombok provided org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 2.x/chapter8-2/src/main/java/com/didispace/chapter82/Chapter82Application.java ================================================ package com.didispace.chapter82; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 程序猿DD * @version 1.0.0 * @blog https://blog.didispace.com */ @Slf4j @SpringBootApplication public class Chapter82Application { public static void main(String[] args) { SpringApplication.run(Chapter82Application.class, args); log.error("Hello World"); log.warn("Hello World"); log.info("Hello World"); log.debug("Hello World"); log.trace("Hello World"); } } ================================================ FILE: 2.x/chapter8-2/src/main/resources/application.properties ================================================ logging.config=classpath:log4j2.xml ================================================ FILE: 2.x/chapter8-2/src/main/resources/log4j2.xml ================================================ ================================================ FILE: 2.x/chapter8-3/pom.xml ================================================ 4.0.0 org.springframework.boot spring-boot-starter-parent 2.6.1 com.didispace chapter8-3 0.0.1-SNAPSHOT 使用tinylog记录日志 UTF-8 1.8 2.4.1 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging org.tinylog tinylog-api ${tinylog.version} org.tinylog tinylog-impl ${tinylog.version} org.tinylog slf4j-tinylog ${tinylog.version} org.tinylog jcl-tinylog ${tinylog.version} org.tinylog log4j1.2-api ${tinylog.version} org.projectlombok lombok provided org.springframework.boot spring-boot-maven-plugin true ================================================ FILE: 2.x/chapter8-3/src/main/java/com/didispace/chapter83/Chapter83Application.java ================================================ package com.didispace.chapter83; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 程序猿DD * @version 1.0.0 * @blog https://blog.didispace.com */ @Slf4j @SpringBootApplication public class Chapter83Application { public static void main(String[] args) { SpringApplication.run(Chapter83Application.class, args); log.error("Hello World"); log.warn("Hello World"); log.info("Hello World"); log.debug("Hello World"); log.trace("Hello World"); } } ================================================ FILE: 2.x/chapter8-3/src/main/resources/application.properties ================================================ ================================================ FILE: 2.x/chapter8-3/src/main/resources/tinylog.properties ================================================ writer=console writer.format={date: HH:mm:ss.SSS} {level}: {message} ================================================ FILE: 2.x/pom.xml ================================================ 4.0.0 com.didispace 2.x 2.0-SNAPSHOT pom 全网Star最多的Spring Boot基础教程 chapter1-1 chapter1-2 chapter1-3 chapter1-4 chapter1-5 chapter2-1 chapter2-2 chapter2-3 chapter2-4 chapter2-5 chapter2-6 chapter2-7 chapter2-8 chapter3-1 chapter3-2 chapter3-3 chapter3-4 chapter3-5 chapter3-6 chapter3-7 chapter3-8 chapter3-9 chapter3-10 chapter3-11 chapter3-12 chapter3-13 chapter4-1 chapter4-2 chapter4-3 chapter4-4 chapter4-5 chapter5-1 chapter5-2 chapter5-3 chapter5-4 chapter5-5 chapter6-1 chapter6-2 chapter6-3 chapter6-4 chapter7-1 chapter7-2 chapter7-3 chapter7-4 chapter7-5 chapter7-6 chapter7-7 chapter7-8 chapter8-1 chapter8-2 chapter8-3 ================================================ FILE: README.md ================================================ # Spring Boot基础教程 **专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程! **如何支持**: 1. 关注我的公众号”**程序猿DD**“ 2. 点个`Star`并`Follow`我 3. 把该仓库分享给更多的朋友 **加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长 **Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章 ## 教程目录 该教程自2016年连载至今,因内容较多,经历过多个版本的迭代。 为方便查看学习,这里重新做了整理,根据1.x版本和2.x版本做了区分汇总,后续还会继续跟进3.x版本! 可以通过下面的链接,进入具体版本的教程目录: - [Spring Boot 2.x](./2.x) - [Spring Boot 1.x](./1.x) > **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
## 推荐内容 - [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容 - [Spring Boot教程](https://blog.didispace.com/spring-boot-learning-2x/):全网Star最多的免费Spring Boot基础教程 - [Spring Cloud教程](https://blog.didispace.com/spring-cloud-learning/):全网最早最全的免费Spring Cloud基础教程 - [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活 **关注公众号,获得更多技术资讯** ================================================ FILE: README_zh.md ================================================ # Spring Boot基础教程 **专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程! **如何支持**: 1. 关注我的公众号”**程序猿DD**“ 2. 点个`Star`并`Follow`我 3. 把该仓库分享给更多的朋友 **加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长 **Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章 ## 教程目录 该教程自2016年连载至今,因内容较多,经历过多个版本的迭代。 为方便查看学习,这里重新做了整理,根据1.x版本和2.x版本做了区分汇总。 可以通过下面的链接,进入具体版本的教程目录: - [Spring Boot 2.x](./2.x) - [Spring Boot 1.x](./1.x) > **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
## 推荐内容 - [我的博客](http://blog.didispace.com):分享平时学习和实践过的技术内容 - [Spring Boot教程](https://blog.didispace.com/spring-boot-learning-2x/):全网Star最多的免费Spring Boot基础教程 - [Spring Cloud教程](https://blog.didispace.com/spring-cloud-learning/):全网最早最全的免费Spring Cloud基础教程 - [知识星球](https://t.xiaomiquan.com/zfEiY3v):聊聊技术人的斜杠生活 **关注公众号,获得更多技术资讯** ================================================ FILE: pom.xml ================================================ 4.0.0 com.didispace SpringBoot-Learning 1.0-SNAPSHOT pom 2.x