diff --git a/1.x/Chapter1/pom.xml b/1.x/Chapter1/pom.xml new file mode 100644 index 00000000..60d479e4 --- /dev/null +++ b/1.x/Chapter1/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter1/src/main/java/com/didispace/Chapter1Application.java b/1.x/Chapter1/src/main/java/com/didispace/Chapter1Application.java new file mode 100755 index 00000000..68232816 --- /dev/null +++ b/1.x/Chapter1/src/main/java/com/didispace/Chapter1Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter1/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter1/src/main/java/com/didispace/web/HelloController.java new file mode 100755 index 00000000..94554856 --- /dev/null +++ b/1.x/Chapter1/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,14 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter1/src/main/resources/application.properties b/1.x/Chapter1/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter1/src/test/java/com/didispace/Chapter1ApplicationTests.java b/1.x/Chapter1/src/test/java/com/didispace/Chapter1ApplicationTests.java new file mode 100755 index 00000000..0b5bfb0f --- /dev/null +++ b/1.x/Chapter1/src/test/java/com/didispace/Chapter1ApplicationTests.java @@ -0,0 +1,40 @@ +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"))); + } + +} diff --git a/1.x/Chapter2-1-1/pom.xml b/1.x/Chapter2-1-1/pom.xml new file mode 100644 index 00000000..c85c4053 --- /dev/null +++ b/1.x/Chapter2-1-1/pom.xml @@ -0,0 +1,55 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter2-1-1/src/main/java/com/didispace/Application.java b/1.x/Chapter2-1-1/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter2-1-1/src/main/java/com/didispace/service/BlogProperties.java b/1.x/Chapter2-1-1/src/main/java/com/didispace/service/BlogProperties.java new file mode 100644 index 00000000..63de02ad --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/java/com/didispace/service/BlogProperties.java @@ -0,0 +1,96 @@ +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; + } +} diff --git a/1.x/Chapter2-1-1/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter2-1-1/src/main/java/com/didispace/web/HelloController.java new file mode 100755 index 00000000..58c767ef --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,21 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter2-1-1/src/main/resources/application-dev.properties b/1.x/Chapter2-1-1/src/main/resources/application-dev.properties new file mode 100755 index 00000000..bbeee1fd --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/resources/application-dev.properties @@ -0,0 +1,2 @@ +# 服务端口 +server.port=1111 \ No newline at end of file diff --git a/1.x/Chapter2-1-1/src/main/resources/application-prod.properties b/1.x/Chapter2-1-1/src/main/resources/application-prod.properties new file mode 100755 index 00000000..2b3fdee2 --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/resources/application-prod.properties @@ -0,0 +1,2 @@ +# 服务端口 +server.port=3333 \ No newline at end of file diff --git a/1.x/Chapter2-1-1/src/main/resources/application-test.properties b/1.x/Chapter2-1-1/src/main/resources/application-test.properties new file mode 100755 index 00000000..717d776f --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/resources/application-test.properties @@ -0,0 +1,2 @@ +# 服务端口 +server.port=2222 \ No newline at end of file diff --git a/1.x/Chapter2-1-1/src/main/resources/application.properties b/1.x/Chapter2-1-1/src/main/resources/application.properties new file mode 100755 index 00000000..b2582fb4 --- /dev/null +++ b/1.x/Chapter2-1-1/src/main/resources/application.properties @@ -0,0 +1,17 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter2-1-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter2-1-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..0ad72479 --- /dev/null +++ b/1.x/Chapter2-1-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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()); + + } + +} diff --git a/1.x/Chapter2-1-2/pom.xml b/1.x/Chapter2-1-2/pom.xml new file mode 100644 index 00000000..f869ccfc --- /dev/null +++ b/1.x/Chapter2-1-2/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/Application.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..bcfd43a8 --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/Application.java @@ -0,0 +1,31 @@ +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..."); + } + } + +} diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationEnvironmentPreparedEventListener.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationEnvironmentPreparedEventListener.java new file mode 100644 index 00000000..da2a47cb --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationEnvironmentPreparedEventListener.java @@ -0,0 +1,15 @@ +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......"); + } + +} diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationFailedEventListener.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationFailedEventListener.java new file mode 100644 index 00000000..457ff47f --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationFailedEventListener.java @@ -0,0 +1,15 @@ +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......"); + } + +} diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationPreparedEventListener.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationPreparedEventListener.java new file mode 100644 index 00000000..5b529617 --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationPreparedEventListener.java @@ -0,0 +1,15 @@ +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......"); + } + +} diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationReadyEventListener.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationReadyEventListener.java new file mode 100644 index 00000000..9193a750 --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationReadyEventListener.java @@ -0,0 +1,15 @@ +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......"); + } + +} diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartedEventListener.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartedEventListener.java new file mode 100644 index 00000000..3b47eba6 --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartedEventListener.java @@ -0,0 +1,16 @@ +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......"); + } + +} diff --git a/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartingEventListener.java b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartingEventListener.java new file mode 100644 index 00000000..effcb14f --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartingEventListener.java @@ -0,0 +1,15 @@ +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......"); + } + +} diff --git a/1.x/Chapter2-1-2/src/main/resources/META-INF/spring.factories b/1.x/Chapter2-1-2/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..15177da6 --- /dev/null +++ b/1.x/Chapter2-1-2/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.context.ApplicationListener=com.didispace.ApplicationEnvironmentPreparedEventListener,\ + com.didispace.ApplicationFailedEventListener,\ + com.didispace.ApplicationPreparedEventListener,\ + com.didispace.ApplicationReadyEventListener,\ + com.didispace.ApplicationStartedEventListener,\ + com.didispace.ApplicationStartingEventListener \ No newline at end of file diff --git a/1.x/Chapter2-1-2/src/main/resources/application.properties b/1.x/Chapter2-1-2/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter2-2-1/pom.xml b/1.x/Chapter2-2-1/pom.xml new file mode 100644 index 00000000..c7eddd26 --- /dev/null +++ b/1.x/Chapter2-2-1/pom.xml @@ -0,0 +1,49 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter2-2-1/src/main/java/com/didispace/Application.java b/1.x/Chapter2-2-1/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f06a4a25 --- /dev/null +++ b/1.x/Chapter2-2-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,44 @@ +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")); + + } + +} diff --git a/1.x/Chapter2-2-1/src/main/java/com/didispace/FooProperties.java b/1.x/Chapter2-2-1/src/main/java/com/didispace/FooProperties.java new file mode 100644 index 00000000..9fdf6e22 --- /dev/null +++ b/1.x/Chapter2-2-1/src/main/java/com/didispace/FooProperties.java @@ -0,0 +1,14 @@ +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; + +} \ No newline at end of file diff --git a/1.x/Chapter2-2-1/src/main/java/com/didispace/PostInfo.java b/1.x/Chapter2-2-1/src/main/java/com/didispace/PostInfo.java new file mode 100644 index 00000000..6df554fe --- /dev/null +++ b/1.x/Chapter2-2-1/src/main/java/com/didispace/PostInfo.java @@ -0,0 +1,13 @@ +package com.didispace; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@Data +@ConfigurationProperties +public class PostInfo { + + private String title; + private String content; + +} diff --git a/1.x/Chapter2-2-1/src/main/resources/application.properties b/1.x/Chapter2-2-1/src/main/resources/application.properties new file mode 100755 index 00000000..df1d5f5a --- /dev/null +++ b/1.x/Chapter2-2-1/src/main/resources/application.properties @@ -0,0 +1,10 @@ +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! diff --git a/1.x/Chapter3-1-1/pom.xml b/1.x/Chapter3-1-1/pom.xml new file mode 100644 index 00000000..b9c2cc8e --- /dev/null +++ b/1.x/Chapter3-1-1/pom.xml @@ -0,0 +1,55 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-1-1/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-1/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter3-1-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter3-1-1/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-1-1/src/main/java/com/didispace/domain/User.java new file mode 100755 index 00000000..208cfe32 --- /dev/null +++ b/1.x/Chapter3-1-1/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,41 @@ +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; + } +} diff --git a/1.x/Chapter3-1-1/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter3-1-1/src/main/java/com/didispace/web/HelloController.java new file mode 100755 index 00000000..58c767ef --- /dev/null +++ b/1.x/Chapter3-1-1/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,21 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-1/src/main/java/com/didispace/web/UserController.java b/1.x/Chapter3-1-1/src/main/java/com/didispace/web/UserController.java new file mode 100755 index 00000000..f5c7ee16 --- /dev/null +++ b/1.x/Chapter3-1-1/src/main/java/com/didispace/web/UserController.java @@ -0,0 +1,62 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-1/src/main/resources/application.properties b/1.x/Chapter3-1-1/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-1-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..11609864 --- /dev/null +++ b/1.x/Chapter3-1-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,104 @@ +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("[]"))); + + } + +} diff --git a/1.x/Chapter3-1-2/pom.xml b/1.x/Chapter3-1-2/pom.xml new file mode 100644 index 00000000..03673630 --- /dev/null +++ b/1.x/Chapter3-1-2/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-1-2/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-2/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter3-1-2/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter3-1-2/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter3-1-2/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..07185c5e --- /dev/null +++ b/1.x/Chapter3-1-2/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,30 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-2/src/main/resources/application.properties b/1.x/Chapter3-1-2/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-2/src/main/resources/templates/index.html b/1.x/Chapter3-1-2/src/main/resources/templates/index.html new file mode 100755 index 00000000..32cbfe84 --- /dev/null +++ b/1.x/Chapter3-1-2/src/main/resources/templates/index.html @@ -0,0 +1,10 @@ + + + + + + + +

Hello World

+ + \ No newline at end of file diff --git a/1.x/Chapter3-1-2/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-1-2/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..c5b2e60c --- /dev/null +++ b/1.x/Chapter3-1-2/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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"))); + } + +} diff --git a/1.x/Chapter3-1-3/pom.xml b/1.x/Chapter3-1-3/pom.xml new file mode 100755 index 00000000..71d874b2 --- /dev/null +++ b/1.x/Chapter3-1-3/pom.xml @@ -0,0 +1,63 @@ + + + 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 + + + + + + + diff --git a/1.x/Chapter3-1-3/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-3/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter3-1-3/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter3-1-3/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter3-1-3/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..11f8c65f --- /dev/null +++ b/1.x/Chapter3-1-3/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,30 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-3/src/main/resources/application.properties b/1.x/Chapter3-1-3/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-3/src/main/resources/templates/index.ftl b/1.x/Chapter3-1-3/src/main/resources/templates/index.ftl new file mode 100755 index 00000000..b5a7ae93 --- /dev/null +++ b/1.x/Chapter3-1-3/src/main/resources/templates/index.ftl @@ -0,0 +1,11 @@ + + + + + + + +FreeMarker模板引擎 +

${host}

+ + \ No newline at end of file diff --git a/1.x/Chapter3-1-3/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-1-3/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..c5b2e60c --- /dev/null +++ b/1.x/Chapter3-1-3/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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"))); + } + +} diff --git a/1.x/Chapter3-1-4/pom.xml b/1.x/Chapter3-1-4/pom.xml new file mode 100755 index 00000000..c7f70586 --- /dev/null +++ b/1.x/Chapter3-1-4/pom.xml @@ -0,0 +1,63 @@ + + + 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 + + + + + + + diff --git a/1.x/Chapter3-1-4/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-4/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter3-1-4/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter3-1-4/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter3-1-4/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..11f8c65f --- /dev/null +++ b/1.x/Chapter3-1-4/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,30 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-4/src/main/resources/application.properties b/1.x/Chapter3-1-4/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-4/src/main/resources/templates/index.vm b/1.x/Chapter3-1-4/src/main/resources/templates/index.vm new file mode 100755 index 00000000..e9578712 --- /dev/null +++ b/1.x/Chapter3-1-4/src/main/resources/templates/index.vm @@ -0,0 +1,11 @@ + + + + + + + +Velocity模板 +

${host}

+ + \ No newline at end of file diff --git a/1.x/Chapter3-1-4/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-1-4/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..c5b2e60c --- /dev/null +++ b/1.x/Chapter3-1-4/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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"))); + } + +} diff --git a/1.x/Chapter3-1-5/pom.xml b/1.x/Chapter3-1-5/pom.xml new file mode 100755 index 00000000..69068183 --- /dev/null +++ b/1.x/Chapter3-1-5/pom.xml @@ -0,0 +1,66 @@ + + + 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 + + + + + + diff --git a/1.x/Chapter3-1-5/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-5/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter3-1-5/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter3-1-5/src/main/java/com/didispace/Swagger2.java b/1.x/Chapter3-1-5/src/main/java/com/didispace/Swagger2.java new file mode 100644 index 00000000..9d16efa2 --- /dev/null +++ b/1.x/Chapter3-1-5/src/main/java/com/didispace/Swagger2.java @@ -0,0 +1,43 @@ +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(); + } + +} diff --git a/1.x/Chapter3-1-5/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-1-5/src/main/java/com/didispace/domain/User.java new file mode 100755 index 00000000..208cfe32 --- /dev/null +++ b/1.x/Chapter3-1-5/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,41 @@ +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; + } +} diff --git a/1.x/Chapter3-1-5/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter3-1-5/src/main/java/com/didispace/web/HelloController.java new file mode 100755 index 00000000..bc792556 --- /dev/null +++ b/1.x/Chapter3-1-5/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,24 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java b/1.x/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java new file mode 100755 index 00000000..3363bfd9 --- /dev/null +++ b/1.x/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java @@ -0,0 +1,67 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-5/src/main/resources/application.properties b/1.x/Chapter3-1-5/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-6/pom.xml b/1.x/Chapter3-1-6/pom.xml new file mode 100644 index 00000000..87ccab37 --- /dev/null +++ b/1.x/Chapter3-1-6/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-1-6/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-6/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter3-1-6/src/main/java/com/didispace/dto/ErrorInfo.java b/1.x/Chapter3-1-6/src/main/java/com/didispace/dto/ErrorInfo.java new file mode 100644 index 00000000..1c1034bb --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/java/com/didispace/dto/ErrorInfo.java @@ -0,0 +1,53 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-6/src/main/java/com/didispace/exception/GlobalExceptionHandler.java b/1.x/Chapter3-1-6/src/main/java/com/didispace/exception/GlobalExceptionHandler.java new file mode 100644 index 00000000..45d5f0ec --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/java/com/didispace/exception/GlobalExceptionHandler.java @@ -0,0 +1,35 @@ +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; + } + +} + diff --git a/1.x/Chapter3-1-6/src/main/java/com/didispace/exception/MyException.java b/1.x/Chapter3-1-6/src/main/java/com/didispace/exception/MyException.java new file mode 100644 index 00000000..e6c179e2 --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/java/com/didispace/exception/MyException.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter3-1-6/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter3-1-6/src/main/java/com/didispace/web/HelloController.java new file mode 100755 index 00000000..01e5d50a --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,35 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-6/src/main/resources/application.properties b/1.x/Chapter3-1-6/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-6/src/main/resources/templates/error.html b/1.x/Chapter3-1-6/src/main/resources/templates/error.html new file mode 100755 index 00000000..dc521d18 --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/resources/templates/error.html @@ -0,0 +1,12 @@ + + + + + 统一异常处理 + + +

Error Handler

+
+
+ + \ No newline at end of file diff --git a/1.x/Chapter3-1-6/src/main/resources/templates/index.html b/1.x/Chapter3-1-6/src/main/resources/templates/index.html new file mode 100755 index 00000000..32cbfe84 --- /dev/null +++ b/1.x/Chapter3-1-6/src/main/resources/templates/index.html @@ -0,0 +1,10 @@ + + + + + + + +

Hello World

+ + \ No newline at end of file diff --git a/1.x/Chapter3-1-6/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-1-6/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..964ba2af --- /dev/null +++ b/1.x/Chapter3-1-6/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,35 @@ +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 { + + + +} diff --git a/1.x/Chapter3-1-7/pom.xml b/1.x/Chapter3-1-7/pom.xml new file mode 100644 index 00000000..660637b3 --- /dev/null +++ b/1.x/Chapter3-1-7/pom.xml @@ -0,0 +1,63 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-1-7/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-7/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..7ac57d25 --- /dev/null +++ b/1.x/Chapter3-1-7/src/main/java/com/didispace/Application.java @@ -0,0 +1,58 @@ +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; + } + +} diff --git a/1.x/Chapter3-1-7/src/main/resources/application.properties b/1.x/Chapter3-1-7/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-1-8/pom.xml b/1.x/Chapter3-1-8/pom.xml new file mode 100644 index 00000000..f20ce9a1 --- /dev/null +++ b/1.x/Chapter3-1-8/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-1-8/src/main/java/com/didispace/Application.java b/1.x/Chapter3-1-8/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..a20de910 --- /dev/null +++ b/1.x/Chapter3-1-8/src/main/java/com/didispace/Application.java @@ -0,0 +1,18 @@ +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); + } + +} diff --git a/1.x/Chapter3-1-8/src/main/java/com/didispace/web/User.java b/1.x/Chapter3-1-8/src/main/java/com/didispace/web/User.java new file mode 100755 index 00000000..2ff2af3d --- /dev/null +++ b/1.x/Chapter3-1-8/src/main/java/com/didispace/web/User.java @@ -0,0 +1,26 @@ +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; + +} diff --git a/1.x/Chapter3-1-8/src/main/java/com/didispace/web/UserController.java b/1.x/Chapter3-1-8/src/main/java/com/didispace/web/UserController.java new file mode 100755 index 00000000..2b26f6e2 --- /dev/null +++ b/1.x/Chapter3-1-8/src/main/java/com/didispace/web/UserController.java @@ -0,0 +1,25 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-1-8/src/main/resources/application.properties b/1.x/Chapter3-1-8/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/1.x/Chapter3-2-1/pom.xml b/1.x/Chapter3-2-1/pom.xml new file mode 100644 index 00000000..f993f502 --- /dev/null +++ b/1.x/Chapter3-2-1/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-1/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-1/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserService.java b/1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserService.java new file mode 100644 index 00000000..620a443f --- /dev/null +++ b/1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserService.java @@ -0,0 +1,35 @@ +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(); + + +} diff --git a/1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserServiceImpl.java b/1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserServiceImpl.java new file mode 100644 index 00000000..769595d5 --- /dev/null +++ b/1.x/Chapter3-2-1/src/main/java/com/didispace/service/UserServiceImpl.java @@ -0,0 +1,38 @@ +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"); + } +} diff --git a/1.x/Chapter3-2-1/src/main/resources/application.properties b/1.x/Chapter3-2-1/src/main/resources/application.properties new file mode 100644 index 00000000..4215c2c6 --- /dev/null +++ b/1.x/Chapter3-2-1/src/main/resources/application.properties @@ -0,0 +1,4 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-2-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..39aacb79 --- /dev/null +++ b/1.x/Chapter3-2-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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()); + + } + + +} diff --git a/1.x/Chapter3-2-10/pom.xml b/1.x/Chapter3-2-10/pom.xml new file mode 100644 index 00000000..a5527fc2 --- /dev/null +++ b/1.x/Chapter3-2-10/pom.xml @@ -0,0 +1,66 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-10/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-10/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-10/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-10/src/main/java/com/didispace/Person.java b/1.x/Chapter3-2-10/src/main/java/com/didispace/Person.java new file mode 100644 index 00000000..fbbb8d3b --- /dev/null +++ b/1.x/Chapter3-2-10/src/main/java/com/didispace/Person.java @@ -0,0 +1,22 @@ +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; + +} diff --git a/1.x/Chapter3-2-10/src/main/java/com/didispace/PersonRepository.java b/1.x/Chapter3-2-10/src/main/java/com/didispace/PersonRepository.java new file mode 100644 index 00000000..a02bd2bd --- /dev/null +++ b/1.x/Chapter3-2-10/src/main/java/com/didispace/PersonRepository.java @@ -0,0 +1,10 @@ +package com.didispace; + +import org.springframework.data.repository.CrudRepository; + +import javax.naming.Name; + +public interface PersonRepository extends CrudRepository { + + +} \ No newline at end of file diff --git a/1.x/Chapter3-2-10/src/main/resources/application.properties b/1.x/Chapter3-2-10/src/main/resources/application.properties new file mode 100644 index 00000000..4b3fab0b --- /dev/null +++ b/1.x/Chapter3-2-10/src/main/resources/application.properties @@ -0,0 +1,4 @@ +#spring.ldap.urls=ldap://localhost:1235 +#spring.ldap.base=dc=didispace,dc=com +#spring.ldap.username=didispace +#spring.ldap.password=123456 \ No newline at end of file diff --git a/1.x/Chapter3-2-10/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-10/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..dc188774 --- /dev/null +++ b/1.x/Chapter3-2-10/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,39 @@ +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); + }); + } + +} diff --git a/1.x/Chapter3-2-10/src/test/resources/application.properties b/1.x/Chapter3-2-10/src/test/resources/application.properties new file mode 100644 index 00000000..08bbb56b --- /dev/null +++ b/1.x/Chapter3-2-10/src/test/resources/application.properties @@ -0,0 +1,3 @@ +spring.ldap.embedded.ldif=ldap-server.ldif +spring.ldap.embedded.base-dn=dc=didispace,dc=com + diff --git a/1.x/Chapter3-2-10/src/test/resources/ldap-server.ldif b/1.x/Chapter3-2-10/src/test/resources/ldap-server.ldif new file mode 100644 index 00000000..4eac0611 --- /dev/null +++ b/1.x/Chapter3-2-10/src/test/resources/ldap-server.ldif @@ -0,0 +1,18 @@ +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= diff --git a/1.x/Chapter3-2-11/pom.xml b/1.x/Chapter3-2-11/pom.xml new file mode 100755 index 00000000..d9ac4cf1 --- /dev/null +++ b/1.x/Chapter3-2-11/pom.xml @@ -0,0 +1,68 @@ + + + 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 + + + + + + diff --git a/1.x/Chapter3-2-11/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-11/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..89042041 --- /dev/null +++ b/1.x/Chapter3-2-11/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-11/src/main/resources/application.properties b/1.x/Chapter3-2-11/src/main/resources/application.properties new file mode 100644 index 00000000..e3f19a14 --- /dev/null +++ b/1.x/Chapter3-2-11/src/main/resources/application.properties @@ -0,0 +1,4 @@ +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 diff --git a/1.x/Chapter3-2-11/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-11/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..b3671364 --- /dev/null +++ b/1.x/Chapter3-2-11/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,27 @@ +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()); + } + +} diff --git a/1.x/Chapter3-2-2/pom.xml b/1.x/Chapter3-2-2/pom.xml new file mode 100644 index 00000000..4312b920 --- /dev/null +++ b/1.x/Chapter3-2-2/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-2/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-2/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-2/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-2/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-2-2/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..6afe6960 --- /dev/null +++ b/1.x/Chapter3-2-2/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,58 @@ +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; + } + +} diff --git a/1.x/Chapter3-2-2/src/main/java/com/didispace/domain/UserRepository.java b/1.x/Chapter3-2-2/src/main/java/com/didispace/domain/UserRepository.java new file mode 100644 index 00000000..6bc94427 --- /dev/null +++ b/1.x/Chapter3-2-2/src/main/java/com/didispace/domain/UserRepository.java @@ -0,0 +1,24 @@ +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); + + +} diff --git a/1.x/Chapter3-2-2/src/main/resources/application.properties b/1.x/Chapter3-2-2/src/main/resources/application.properties new file mode 100755 index 00000000..2df621df --- /dev/null +++ b/1.x/Chapter3-2-2/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-2-2/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-2/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..dd6628d3 --- /dev/null +++ b/1.x/Chapter3-2-2/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,56 @@ +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()); + + } + + +} diff --git a/1.x/Chapter3-2-3/pom.xml b/1.x/Chapter3-2-3/pom.xml new file mode 100644 index 00000000..4de3b90f --- /dev/null +++ b/1.x/Chapter3-2-3/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-3/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-3/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..c8fee3c0 --- /dev/null +++ b/1.x/Chapter3-2-3/src/main/java/com/didispace/Application.java @@ -0,0 +1,20 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-3/src/main/java/com/didispace/DataSourceConfig.java b/1.x/Chapter3-2-3/src/main/java/com/didispace/DataSourceConfig.java new file mode 100644 index 00000000..96224196 --- /dev/null +++ b/1.x/Chapter3-2-3/src/main/java/com/didispace/DataSourceConfig.java @@ -0,0 +1,49 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-3/src/main/resources/application.properties b/1.x/Chapter3-2-3/src/main/resources/application.properties new file mode 100755 index 00000000..b437ea4f --- /dev/null +++ b/1.x/Chapter3-2-3/src/main/resources/application.properties @@ -0,0 +1,9 @@ +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 diff --git a/1.x/Chapter3-2-3/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-3/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..f8e99e69 --- /dev/null +++ b/1.x/Chapter3-2-3/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,51 @@ +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)); + + } + + +} diff --git a/1.x/Chapter3-2-4/pom.xml b/1.x/Chapter3-2-4/pom.xml new file mode 100644 index 00000000..766c2a3f --- /dev/null +++ b/1.x/Chapter3-2-4/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..c8fee3c0 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/Application.java @@ -0,0 +1,20 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/DataSourceConfig.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/DataSourceConfig.java new file mode 100644 index 00000000..07377475 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/DataSourceConfig.java @@ -0,0 +1,36 @@ +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(); + } + +} diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/PrimaryConfig.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/PrimaryConfig.java new file mode 100644 index 00000000..abdb2e53 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/PrimaryConfig.java @@ -0,0 +1,61 @@ +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()); + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/SecondaryConfig.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/SecondaryConfig.java new file mode 100644 index 00000000..38890f50 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/SecondaryConfig.java @@ -0,0 +1,57 @@ +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()); + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/User.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/User.java new file mode 100644 index 00000000..7d7b1072 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/User.java @@ -0,0 +1,58 @@ +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; + } + +} diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/UserRepository.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/UserRepository.java new file mode 100644 index 00000000..22266886 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/p/UserRepository.java @@ -0,0 +1,17 @@ +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 { + + +} diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/Message.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/Message.java new file mode 100644 index 00000000..33d3022f --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/Message.java @@ -0,0 +1,58 @@ +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; + } + +} diff --git a/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/MessageRepository.java b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/MessageRepository.java new file mode 100644 index 00000000..27f22b4b --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/java/com/didispace/domain/s/MessageRepository.java @@ -0,0 +1,15 @@ +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 { + + +} diff --git a/1.x/Chapter3-2-4/src/main/resources/application.properties b/1.x/Chapter3-2-4/src/main/resources/application.properties new file mode 100755 index 00000000..67caf122 --- /dev/null +++ b/1.x/Chapter3-2-4/src/main/resources/application.properties @@ -0,0 +1,11 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-2-4/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-4/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..2ea22308 --- /dev/null +++ b/1.x/Chapter3-2-4/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,49 @@ +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()); + + } + + +} diff --git a/1.x/Chapter3-2-5/pom.xml b/1.x/Chapter3-2-5/pom.xml new file mode 100644 index 00000000..ff2f19c4 --- /dev/null +++ b/1.x/Chapter3-2-5/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-5/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-5/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-5/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-5/src/main/java/com/didispace/RedisConfig.java b/1.x/Chapter3-2-5/src/main/java/com/didispace/RedisConfig.java new file mode 100644 index 00000000..cf103ff0 --- /dev/null +++ b/1.x/Chapter3-2-5/src/main/java/com/didispace/RedisConfig.java @@ -0,0 +1,35 @@ +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; + } + + +} diff --git a/1.x/Chapter3-2-5/src/main/java/com/didispace/RedisObjectSerializer.java b/1.x/Chapter3-2-5/src/main/java/com/didispace/RedisObjectSerializer.java new file mode 100644 index 00000000..9aecc442 --- /dev/null +++ b/1.x/Chapter3-2-5/src/main/java/com/didispace/RedisObjectSerializer.java @@ -0,0 +1,43 @@ +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); + } +} \ No newline at end of file diff --git a/1.x/Chapter3-2-5/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-2-5/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..41615193 --- /dev/null +++ b/1.x/Chapter3-2-5/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,39 @@ +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; + } + +} diff --git a/1.x/Chapter3-2-5/src/main/resources/application.properties b/1.x/Chapter3-2-5/src/main/resources/application.properties new file mode 100644 index 00000000..37bc1387 --- /dev/null +++ b/1.x/Chapter3-2-5/src/main/resources/application.properties @@ -0,0 +1,21 @@ +# 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 + + diff --git a/1.x/Chapter3-2-5/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-5/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..35594ea5 --- /dev/null +++ b/1.x/Chapter3-2-5/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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()); + + } + +} diff --git a/1.x/Chapter3-2-6/pom.xml b/1.x/Chapter3-2-6/pom.xml new file mode 100755 index 00000000..a060bc0c --- /dev/null +++ b/1.x/Chapter3-2-6/pom.xml @@ -0,0 +1,55 @@ + + + 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 + + + + + + diff --git a/1.x/Chapter3-2-6/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-6/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-6/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-6/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-2-6/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..bfff180b --- /dev/null +++ b/1.x/Chapter3-2-6/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,48 @@ +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; + } +} diff --git a/1.x/Chapter3-2-6/src/main/java/com/didispace/domain/UserRepository.java b/1.x/Chapter3-2-6/src/main/java/com/didispace/domain/UserRepository.java new file mode 100644 index 00000000..073231e5 --- /dev/null +++ b/1.x/Chapter3-2-6/src/main/java/com/didispace/domain/UserRepository.java @@ -0,0 +1,15 @@ +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); + +} diff --git a/1.x/Chapter3-2-6/src/main/resources/application.properties b/1.x/Chapter3-2-6/src/main/resources/application.properties new file mode 100644 index 00000000..65cdd338 --- /dev/null +++ b/1.x/Chapter3-2-6/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test + + diff --git a/1.x/Chapter3-2-6/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-6/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..d59751cd --- /dev/null +++ b/1.x/Chapter3-2-6/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,47 @@ +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()); + + } + +} diff --git a/1.x/Chapter3-2-7/pom.xml b/1.x/Chapter3-2-7/pom.xml new file mode 100644 index 00000000..ba19038a --- /dev/null +++ b/1.x/Chapter3-2-7/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-7/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-7/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-7/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-7/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-2-7/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..2348d540 --- /dev/null +++ b/1.x/Chapter3-2-7/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,33 @@ +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; + } + +} diff --git a/1.x/Chapter3-2-7/src/main/java/com/didispace/domain/UserMapper.java b/1.x/Chapter3-2-7/src/main/java/com/didispace/domain/UserMapper.java new file mode 100644 index 00000000..0b95b125 --- /dev/null +++ b/1.x/Chapter3-2-7/src/main/java/com/didispace/domain/UserMapper.java @@ -0,0 +1,14 @@ +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); + +} \ No newline at end of file diff --git a/1.x/Chapter3-2-7/src/main/resources/application.properties b/1.x/Chapter3-2-7/src/main/resources/application.properties new file mode 100644 index 00000000..7aa1af45 --- /dev/null +++ b/1.x/Chapter3-2-7/src/main/resources/application.properties @@ -0,0 +1,4 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-2-7/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-7/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..d46f2f6e --- /dev/null +++ b/1.x/Chapter3-2-7/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,31 @@ +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()); + } + +} \ No newline at end of file diff --git a/1.x/Chapter3-2-8/pom.xml b/1.x/Chapter3-2-8/pom.xml new file mode 100644 index 00000000..0049b2b0 --- /dev/null +++ b/1.x/Chapter3-2-8/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-8/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-8/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-8/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-8/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-2-8/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..cfcc47d4 --- /dev/null +++ b/1.x/Chapter3-2-8/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,47 @@ +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; + } + +} diff --git a/1.x/Chapter3-2-8/src/main/java/com/didispace/domain/UserMapper.java b/1.x/Chapter3-2-8/src/main/java/com/didispace/domain/UserMapper.java new file mode 100644 index 00000000..b0d82e40 --- /dev/null +++ b/1.x/Chapter3-2-8/src/main/java/com/didispace/domain/UserMapper.java @@ -0,0 +1,36 @@ +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); + +} \ No newline at end of file diff --git a/1.x/Chapter3-2-8/src/main/resources/application.properties b/1.x/Chapter3-2-8/src/main/resources/application.properties new file mode 100644 index 00000000..7aa1af45 --- /dev/null +++ b/1.x/Chapter3-2-8/src/main/resources/application.properties @@ -0,0 +1,4 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-2-8/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-8/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..6a91c2e1 --- /dev/null +++ b/1.x/Chapter3-2-8/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,63 @@ +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()); + } + + } + +} diff --git a/1.x/Chapter3-2-9/pom.xml b/1.x/Chapter3-2-9/pom.xml new file mode 100644 index 00000000..73052707 --- /dev/null +++ b/1.x/Chapter3-2-9/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-2-9/src/main/java/com/didispace/Application.java b/1.x/Chapter3-2-9/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-2-9/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserService.java b/1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserService.java new file mode 100644 index 00000000..620a443f --- /dev/null +++ b/1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserService.java @@ -0,0 +1,35 @@ +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(); + + +} diff --git a/1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserServiceImpl.java b/1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserServiceImpl.java new file mode 100644 index 00000000..05c04f09 --- /dev/null +++ b/1.x/Chapter3-2-9/src/main/java/com/didispace/service/UserServiceImpl.java @@ -0,0 +1,38 @@ +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"); + } +} diff --git a/1.x/Chapter3-2-9/src/main/resources/application.properties b/1.x/Chapter3-2-9/src/main/resources/application.properties new file mode 100644 index 00000000..39713b50 --- /dev/null +++ b/1.x/Chapter3-2-9/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-2-9/src/main/resources/db/V1__Base_version.sql b/1.x/Chapter3-2-9/src/main/resources/db/V1__Base_version.sql new file mode 100644 index 00000000..ff8bce17 --- /dev/null +++ b/1.x/Chapter3-2-9/src/main/resources/db/V1__Base_version.sql @@ -0,0 +1,9 @@ +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; diff --git a/1.x/Chapter3-2-9/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-2-9/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..ec6f8985 --- /dev/null +++ b/1.x/Chapter3-2-9/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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()); + + } + + +} diff --git a/1.x/Chapter3-3-1/pom.xml b/1.x/Chapter3-3-1/pom.xml new file mode 100644 index 00000000..53e94b9f --- /dev/null +++ b/1.x/Chapter3-3-1/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter3-3-1/src/main/java/com/didispace/Application.java b/1.x/Chapter3-3-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter3-3-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter3-3-1/src/main/java/com/didispace/domain/User.java b/1.x/Chapter3-3-1/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..11e13ac6 --- /dev/null +++ b/1.x/Chapter3-3-1/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,58 @@ +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; + } + +} diff --git a/1.x/Chapter3-3-1/src/main/java/com/didispace/domain/UserRepository.java b/1.x/Chapter3-3-1/src/main/java/com/didispace/domain/UserRepository.java new file mode 100644 index 00000000..6bc94427 --- /dev/null +++ b/1.x/Chapter3-3-1/src/main/java/com/didispace/domain/UserRepository.java @@ -0,0 +1,24 @@ +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); + + +} diff --git a/1.x/Chapter3-3-1/src/main/java/com/didispace/service/UserService.java b/1.x/Chapter3-3-1/src/main/java/com/didispace/service/UserService.java new file mode 100644 index 00000000..de6745d6 --- /dev/null +++ b/1.x/Chapter3-3-1/src/main/java/com/didispace/service/UserService.java @@ -0,0 +1,17 @@ +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); + +} diff --git a/1.x/Chapter3-3-1/src/main/resources/application.properties b/1.x/Chapter3-3-1/src/main/resources/application.properties new file mode 100644 index 00000000..aa6a7e65 --- /dev/null +++ b/1.x/Chapter3-3-1/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter3-3-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter3-3-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..4b5bbb9f --- /dev/null +++ b/1.x/Chapter3-3-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,58 @@ +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()); + + } + + +} diff --git a/1.x/Chapter4-1-1/pom.xml b/1.x/Chapter4-1-1/pom.xml new file mode 100644 index 00000000..6af0e728 --- /dev/null +++ b/1.x/Chapter4-1-1/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-1-1/src/main/java/com/didispace/Application.java b/1.x/Chapter4-1-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..b9722349 --- /dev/null +++ b/1.x/Chapter4-1-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter4-1-1/src/main/java/com/didispace/task/ScheduledTasks.java b/1.x/Chapter4-1-1/src/main/java/com/didispace/task/ScheduledTasks.java new file mode 100644 index 00000000..1c19e674 --- /dev/null +++ b/1.x/Chapter4-1-1/src/main/java/com/didispace/task/ScheduledTasks.java @@ -0,0 +1,19 @@ +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())); + } + +} diff --git a/1.x/Chapter4-1-1/src/main/resources/application.properties b/1.x/Chapter4-1-1/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-1-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-1-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..22c3fe63 --- /dev/null +++ b/1.x/Chapter4-1-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,18 @@ +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 { + } + +} diff --git a/1.x/Chapter4-1-2/pom.xml b/1.x/Chapter4-1-2/pom.xml new file mode 100644 index 00000000..b25e68b8 --- /dev/null +++ b/1.x/Chapter4-1-2/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-1-2/src/main/java/com/didispace/Application.java b/1.x/Chapter4-1-2/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..aa4d3f13 --- /dev/null +++ b/1.x/Chapter4-1-2/src/main/java/com/didispace/Application.java @@ -0,0 +1,16 @@ +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); + } + +} diff --git a/1.x/Chapter4-1-2/src/main/java/com/didispace/async/Task.java b/1.x/Chapter4-1-2/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..d095878f --- /dev/null +++ b/1.x/Chapter4-1-2/src/main/java/com/didispace/async/Task.java @@ -0,0 +1,51 @@ +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<>("任务三完成"); + } + +} diff --git a/1.x/Chapter4-1-2/src/main/resources/application.properties b/1.x/Chapter4-1-2/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-1-2/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-1-2/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..d6f26efd --- /dev/null +++ b/1.x/Chapter4-1-2/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,43 @@ +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) + "毫秒"); + + } + +} diff --git a/1.x/Chapter4-1-3/pom.xml b/1.x/Chapter4-1-3/pom.xml new file mode 100644 index 00000000..b72b7802 --- /dev/null +++ b/1.x/Chapter4-1-3/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-1-3/src/main/java/com/didispace/Application.java b/1.x/Chapter4-1-3/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..84d84ef2 --- /dev/null +++ b/1.x/Chapter4-1-3/src/main/java/com/didispace/Application.java @@ -0,0 +1,38 @@ +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; + } + } + +} diff --git a/1.x/Chapter4-1-3/src/main/java/com/didispace/async/Task.java b/1.x/Chapter4-1-3/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..07891f82 --- /dev/null +++ b/1.x/Chapter4-1-3/src/main/java/com/didispace/async/Task.java @@ -0,0 +1,48 @@ +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) + "毫秒"); + } + +} diff --git a/1.x/Chapter4-1-3/src/main/resources/application.properties b/1.x/Chapter4-1-3/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-1-3/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-1-3/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..03d3fab7 --- /dev/null +++ b/1.x/Chapter4-1-3/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,28 @@ +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(); + } + +} diff --git a/1.x/Chapter4-1-4/pom.xml b/1.x/Chapter4-1-4/pom.xml new file mode 100644 index 00000000..c8b4be29 --- /dev/null +++ b/1.x/Chapter4-1-4/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-1-4/src/main/java/com/didispace/Application.java b/1.x/Chapter4-1-4/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..5de0f631 --- /dev/null +++ b/1.x/Chapter4-1-4/src/main/java/com/didispace/Application.java @@ -0,0 +1,36 @@ +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; + } + + } + +} diff --git a/1.x/Chapter4-1-4/src/main/java/com/didispace/async/Task.java b/1.x/Chapter4-1-4/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..ac0b102c --- /dev/null +++ b/1.x/Chapter4-1-4/src/main/java/com/didispace/async/Task.java @@ -0,0 +1,49 @@ +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) + "毫秒"); + } + +} diff --git a/1.x/Chapter4-1-4/src/main/resources/application.properties b/1.x/Chapter4-1-4/src/main/resources/application.properties new file mode 100644 index 00000000..806eddf3 --- /dev/null +++ b/1.x/Chapter4-1-4/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.redis.pool.max-wait=5000 +spring.redis.pool.max-active=10 diff --git a/1.x/Chapter4-1-4/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-1-4/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..61107f29 --- /dev/null +++ b/1.x/Chapter4-1-4/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,34 @@ +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); + } + } + } + +} diff --git a/1.x/Chapter4-1-5/pom.xml b/1.x/Chapter4-1-5/pom.xml new file mode 100644 index 00000000..524627d6 --- /dev/null +++ b/1.x/Chapter4-1-5/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-1-5/src/main/java/com/didispace/Application.java b/1.x/Chapter4-1-5/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..84d84ef2 --- /dev/null +++ b/1.x/Chapter4-1-5/src/main/java/com/didispace/Application.java @@ -0,0 +1,38 @@ +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; + } + } + +} diff --git a/1.x/Chapter4-1-5/src/main/java/com/didispace/async/Task.java b/1.x/Chapter4-1-5/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..49f5f7e0 --- /dev/null +++ b/1.x/Chapter4-1-5/src/main/java/com/didispace/async/Task.java @@ -0,0 +1,32 @@ +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"); + } + +} diff --git a/1.x/Chapter4-1-5/src/main/resources/application.properties b/1.x/Chapter4-1-5/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-1-5/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-1-5/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..c9cd12fd --- /dev/null +++ b/1.x/Chapter4-1-5/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,29 @@ +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); + } + +} diff --git a/1.x/Chapter4-2-2/pom.xml b/1.x/Chapter4-2-2/pom.xml new file mode 100644 index 00000000..36d6e141 --- /dev/null +++ b/1.x/Chapter4-2-2/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-2-2/src/main/java/com/didispace/Application.java b/1.x/Chapter4-2-2/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..3ad593c6 --- /dev/null +++ b/1.x/Chapter4-2-2/src/main/java/com/didispace/Application.java @@ -0,0 +1,16 @@ +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); + } + +} diff --git a/1.x/Chapter4-2-2/src/main/resources/application.properties b/1.x/Chapter4-2-2/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-2-2/src/main/resources/log4j.properties b/1.x/Chapter4-2-2/src/main/resources/log4j.properties new file mode 100755 index 00000000..38aca2bc --- /dev/null +++ b/1.x/Chapter4-2-2/src/main/resources/log4j.properties @@ -0,0 +1,36 @@ +# 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 + + + + + diff --git a/1.x/Chapter4-2-2/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-2-2/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..5fafc6d2 --- /dev/null +++ b/1.x/Chapter4-2-2/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,23 @@ +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"); + } + +} diff --git a/1.x/Chapter4-2-3/pom.xml b/1.x/Chapter4-2-3/pom.xml new file mode 100644 index 00000000..847ad12a --- /dev/null +++ b/1.x/Chapter4-2-3/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-2-3/src/main/java/com/didispace/Application.java b/1.x/Chapter4-2-3/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..3ad593c6 --- /dev/null +++ b/1.x/Chapter4-2-3/src/main/java/com/didispace/Application.java @@ -0,0 +1,16 @@ +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); + } + +} diff --git a/1.x/Chapter4-2-3/src/main/resources/application-dev.properties b/1.x/Chapter4-2-3/src/main/resources/application-dev.properties new file mode 100644 index 00000000..a02bf59e --- /dev/null +++ b/1.x/Chapter4-2-3/src/main/resources/application-dev.properties @@ -0,0 +1 @@ +logging.level.com.didispace=INFO \ No newline at end of file diff --git a/1.x/Chapter4-2-3/src/main/resources/application-prod.properties b/1.x/Chapter4-2-3/src/main/resources/application-prod.properties new file mode 100644 index 00000000..a02bf59e --- /dev/null +++ b/1.x/Chapter4-2-3/src/main/resources/application-prod.properties @@ -0,0 +1 @@ +logging.level.com.didispace=INFO \ No newline at end of file diff --git a/1.x/Chapter4-2-3/src/main/resources/application-test.properties b/1.x/Chapter4-2-3/src/main/resources/application-test.properties new file mode 100644 index 00000000..35926a87 --- /dev/null +++ b/1.x/Chapter4-2-3/src/main/resources/application-test.properties @@ -0,0 +1 @@ +logging.level.com.didispace=DEBUG \ No newline at end of file diff --git a/1.x/Chapter4-2-3/src/main/resources/application.properties b/1.x/Chapter4-2-3/src/main/resources/application.properties new file mode 100644 index 00000000..257b3064 --- /dev/null +++ b/1.x/Chapter4-2-3/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.profiles.active=dev \ No newline at end of file diff --git a/1.x/Chapter4-2-3/src/main/resources/log4j.properties b/1.x/Chapter4-2-3/src/main/resources/log4j.properties new file mode 100755 index 00000000..538655cf --- /dev/null +++ b/1.x/Chapter4-2-3/src/main/resources/log4j.properties @@ -0,0 +1,36 @@ +# 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 + + + + + diff --git a/1.x/Chapter4-2-3/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-2-3/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..5fafc6d2 --- /dev/null +++ b/1.x/Chapter4-2-3/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,23 @@ +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"); + } + +} diff --git a/1.x/Chapter4-2-4/pom.xml b/1.x/Chapter4-2-4/pom.xml new file mode 100644 index 00000000..c84fa80e --- /dev/null +++ b/1.x/Chapter4-2-4/pom.xml @@ -0,0 +1,72 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-2-4/src/main/java/com/didispace/Application.java b/1.x/Chapter4-2-4/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter4-2-4/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter4-2-4/src/main/java/com/didispace/aspect/WebLogAspect.java b/1.x/Chapter4-2-4/src/main/java/com/didispace/aspect/WebLogAspect.java new file mode 100644 index 00000000..b4c3666a --- /dev/null +++ b/1.x/Chapter4-2-4/src/main/java/com/didispace/aspect/WebLogAspect.java @@ -0,0 +1,63 @@ +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())); + } + + +} + diff --git a/1.x/Chapter4-2-4/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter4-2-4/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..e53c5db3 --- /dev/null +++ b/1.x/Chapter4-2-4/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,20 @@ +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; + } + +} diff --git a/1.x/Chapter4-2-4/src/main/resources/application.properties b/1.x/Chapter4-2-4/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-2-4/src/main/resources/log4j.properties b/1.x/Chapter4-2-4/src/main/resources/log4j.properties new file mode 100755 index 00000000..38aca2bc --- /dev/null +++ b/1.x/Chapter4-2-4/src/main/resources/log4j.properties @@ -0,0 +1,36 @@ +# 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 + + + + + diff --git a/1.x/Chapter4-2-4/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-2-4/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..5fafc6d2 --- /dev/null +++ b/1.x/Chapter4-2-4/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,23 @@ +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"); + } + +} diff --git a/1.x/Chapter4-2-5/pom.xml b/1.x/Chapter4-2-5/pom.xml new file mode 100644 index 00000000..fec3b791 --- /dev/null +++ b/1.x/Chapter4-2-5/pom.xml @@ -0,0 +1,77 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-2-5/src/main/java/com/didispace/Application.java b/1.x/Chapter4-2-5/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter4-2-5/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter4-2-5/src/main/java/com/didispace/aspect/WebLogAspect.java b/1.x/Chapter4-2-5/src/main/java/com/didispace/aspect/WebLogAspect.java new file mode 100644 index 00000000..d5ea75a1 --- /dev/null +++ b/1.x/Chapter4-2-5/src/main/java/com/didispace/aspect/WebLogAspect.java @@ -0,0 +1,86 @@ +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; + } + +} + diff --git a/1.x/Chapter4-2-5/src/main/java/com/didispace/log/MongoAppender.java b/1.x/Chapter4-2-5/src/main/java/com/didispace/log/MongoAppender.java new file mode 100644 index 00000000..e81f511d --- /dev/null +++ b/1.x/Chapter4-2-5/src/main/java/com/didispace/log/MongoAppender.java @@ -0,0 +1,78 @@ +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; + } + +} diff --git a/1.x/Chapter4-2-5/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter4-2-5/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..e53c5db3 --- /dev/null +++ b/1.x/Chapter4-2-5/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,20 @@ +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; + } + +} diff --git a/1.x/Chapter4-2-5/src/main/resources/application.properties b/1.x/Chapter4-2-5/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-2-5/src/main/resources/log4j.properties b/1.x/Chapter4-2-5/src/main/resources/log4j.properties new file mode 100755 index 00000000..36b92b5c --- /dev/null +++ b/1.x/Chapter4-2-5/src/main/resources/log4j.properties @@ -0,0 +1,14 @@ +# 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 diff --git a/1.x/Chapter4-2-5/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-2-5/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..168dfe7e --- /dev/null +++ b/1.x/Chapter4-2-5/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,25 @@ +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 { + + } + +} diff --git a/1.x/Chapter4-2-6/pom.xml b/1.x/Chapter4-2-6/pom.xml new file mode 100644 index 00000000..c2b26e41 --- /dev/null +++ b/1.x/Chapter4-2-6/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + + diff --git a/1.x/Chapter4-2-6/src/main/java/com/didispace/DemoApplication.java b/1.x/Chapter4-2-6/src/main/java/com/didispace/DemoApplication.java new file mode 100644 index 00000000..1ceacb47 --- /dev/null +++ b/1.x/Chapter4-2-6/src/main/java/com/didispace/DemoApplication.java @@ -0,0 +1,28 @@ +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); + } +} diff --git a/1.x/Chapter4-2-6/src/main/resources/application.properties b/1.x/Chapter4-2-6/src/main/resources/application.properties new file mode 100644 index 00000000..edbeeec2 --- /dev/null +++ b/1.x/Chapter4-2-6/src/main/resources/application.properties @@ -0,0 +1 @@ +management.security.enabled=false diff --git a/1.x/Chapter4-2-6/src/test/java/com/didispace/DemoApplicationTests.java b/1.x/Chapter4-2-6/src/test/java/com/didispace/DemoApplicationTests.java new file mode 100644 index 00000000..dbffb487 --- /dev/null +++ b/1.x/Chapter4-2-6/src/test/java/com/didispace/DemoApplicationTests.java @@ -0,0 +1,16 @@ +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() { + } + +} diff --git a/1.x/Chapter4-3-1/pom.xml b/1.x/Chapter4-3-1/pom.xml new file mode 100644 index 00000000..fc274634 --- /dev/null +++ b/1.x/Chapter4-3-1/pom.xml @@ -0,0 +1,66 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-3-1/src/main/java/com/didispace/Application.java b/1.x/Chapter4-3-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter4-3-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter4-3-1/src/main/java/com/didispace/WebSecurityConfig.java b/1.x/Chapter4-3-1/src/main/java/com/didispace/WebSecurityConfig.java new file mode 100644 index 00000000..02f16187 --- /dev/null +++ b/1.x/Chapter4-3-1/src/main/java/com/didispace/WebSecurityConfig.java @@ -0,0 +1,36 @@ +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"); + } + +} \ No newline at end of file diff --git a/1.x/Chapter4-3-1/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter4-3-1/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..0247f865 --- /dev/null +++ b/1.x/Chapter4-3-1/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,33 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter4-3-1/src/main/resources/application.properties b/1.x/Chapter4-3-1/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/1.x/Chapter4-3-1/src/main/resources/templates/hello.html b/1.x/Chapter4-3-1/src/main/resources/templates/hello.html new file mode 100644 index 00000000..51477131 --- /dev/null +++ b/1.x/Chapter4-3-1/src/main/resources/templates/hello.html @@ -0,0 +1,13 @@ + + + + Hello World! + + +

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

+
+ +
+ + \ No newline at end of file diff --git a/1.x/Chapter4-3-1/src/main/resources/templates/index.html b/1.x/Chapter4-3-1/src/main/resources/templates/index.html new file mode 100644 index 00000000..ffe28340 --- /dev/null +++ b/1.x/Chapter4-3-1/src/main/resources/templates/index.html @@ -0,0 +1,12 @@ + + + + Spring Security入门 + + +

欢迎使用Spring Security!

+ +

点击 这里 打个招呼吧

+ + \ No newline at end of file diff --git a/1.x/Chapter4-3-1/src/main/resources/templates/login.html b/1.x/Chapter4-3-1/src/main/resources/templates/login.html new file mode 100644 index 00000000..f5cbe8e2 --- /dev/null +++ b/1.x/Chapter4-3-1/src/main/resources/templates/login.html @@ -0,0 +1,21 @@ + + + + Spring Security Example + + +
+ 用户名或密码错 +
+
+ 您已注销成功 +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/1.x/Chapter4-3-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-3-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..c5b2e60c --- /dev/null +++ b/1.x/Chapter4-3-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,48 @@ +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"))); + } + +} diff --git a/1.x/Chapter4-4-1/pom.xml b/1.x/Chapter4-4-1/pom.xml new file mode 100644 index 00000000..a146394a --- /dev/null +++ b/1.x/Chapter4-4-1/pom.xml @@ -0,0 +1,70 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-4-1/src/main/java/com/didispace/Application.java b/1.x/Chapter4-4-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..cc033944 --- /dev/null +++ b/1.x/Chapter4-4-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,21 @@ +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); + } + +} diff --git a/1.x/Chapter4-4-1/src/main/java/com/didispace/domain/User.java b/1.x/Chapter4-4-1/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..6afe6960 --- /dev/null +++ b/1.x/Chapter4-4-1/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,58 @@ +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; + } + +} diff --git a/1.x/Chapter4-4-1/src/main/java/com/didispace/domain/UserRepository.java b/1.x/Chapter4-4-1/src/main/java/com/didispace/domain/UserRepository.java new file mode 100644 index 00000000..61b4466a --- /dev/null +++ b/1.x/Chapter4-4-1/src/main/java/com/didispace/domain/UserRepository.java @@ -0,0 +1,22 @@ +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); + +} diff --git a/1.x/Chapter4-4-1/src/main/resources/application.properties b/1.x/Chapter4-4-1/src/main/resources/application.properties new file mode 100644 index 00000000..6cfe333b --- /dev/null +++ b/1.x/Chapter4-4-1/src/main/resources/application.properties @@ -0,0 +1,7 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter4-4-1/src/main/resources/ehcache.xml b/1.x/Chapter4-4-1/src/main/resources/ehcache.xml new file mode 100644 index 00000000..c178cc9f --- /dev/null +++ b/1.x/Chapter4-4-1/src/main/resources/ehcache.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-4-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-4-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..2be63021 --- /dev/null +++ b/1.x/Chapter4-4-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,51 @@ +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()); + + } + +} diff --git a/1.x/Chapter4-4-2/pom.xml b/1.x/Chapter4-4-2/pom.xml new file mode 100644 index 00000000..c9590968 --- /dev/null +++ b/1.x/Chapter4-4-2/pom.xml @@ -0,0 +1,71 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-4-2/src/main/java/com/didispace/Application.java b/1.x/Chapter4-4-2/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..cc033944 --- /dev/null +++ b/1.x/Chapter4-4-2/src/main/java/com/didispace/Application.java @@ -0,0 +1,21 @@ +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); + } + +} diff --git a/1.x/Chapter4-4-2/src/main/java/com/didispace/domain/User.java b/1.x/Chapter4-4-2/src/main/java/com/didispace/domain/User.java new file mode 100644 index 00000000..3df80159 --- /dev/null +++ b/1.x/Chapter4-4-2/src/main/java/com/didispace/domain/User.java @@ -0,0 +1,59 @@ +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; + } + +} diff --git a/1.x/Chapter4-4-2/src/main/java/com/didispace/domain/UserRepository.java b/1.x/Chapter4-4-2/src/main/java/com/didispace/domain/UserRepository.java new file mode 100644 index 00000000..e26a1cd1 --- /dev/null +++ b/1.x/Chapter4-4-2/src/main/java/com/didispace/domain/UserRepository.java @@ -0,0 +1,24 @@ +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); + +} diff --git a/1.x/Chapter4-4-2/src/main/resources/application.properties b/1.x/Chapter4-4-2/src/main/resources/application.properties new file mode 100644 index 00000000..248f22c4 --- /dev/null +++ b/1.x/Chapter4-4-2/src/main/resources/application.properties @@ -0,0 +1,16 @@ +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 + diff --git a/1.x/Chapter4-4-2/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-4-2/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..ceacc3b4 --- /dev/null +++ b/1.x/Chapter4-4-2/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,50 @@ +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()); + + } + +} diff --git a/1.x/Chapter4-5-1/pom.xml b/1.x/Chapter4-5-1/pom.xml new file mode 100644 index 00000000..1640972d --- /dev/null +++ b/1.x/Chapter4-5-1/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter4-5-1/src/main/java/com/didispace/Application.java b/1.x/Chapter4-5-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..2a14b751 --- /dev/null +++ b/1.x/Chapter4-5-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter4-5-1/src/main/resources/application.properties b/1.x/Chapter4-5-1/src/main/resources/application.properties new file mode 100644 index 00000000..be54b4f5 --- /dev/null +++ b/1.x/Chapter4-5-1/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/1.x/Chapter4-5-1/src/main/resources/templates/template.vm b/1.x/Chapter4-5-1/src/main/resources/templates/template.vm new file mode 100644 index 00000000..863856e8 --- /dev/null +++ b/1.x/Chapter4-5-1/src/main/resources/templates/template.vm @@ -0,0 +1,5 @@ + + +

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

+ + \ No newline at end of file diff --git a/1.x/Chapter4-5-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter4-5-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..9d1327d5 --- /dev/null +++ b/1.x/Chapter4-5-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,96 @@ +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); + } + +} diff --git a/1.x/Chapter4-5-1/weixin.jpg b/1.x/Chapter4-5-1/weixin.jpg new file mode 100644 index 00000000..89797465 Binary files /dev/null and b/1.x/Chapter4-5-1/weixin.jpg differ diff --git a/1.x/Chapter5-2-1/pom.xml b/1.x/Chapter5-2-1/pom.xml new file mode 100644 index 00000000..36c67096 --- /dev/null +++ b/1.x/Chapter5-2-1/pom.xml @@ -0,0 +1,46 @@ + + + 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 + + + + diff --git a/1.x/Chapter5-2-1/src/main/java/com/didispace/HelloApplication.java b/1.x/Chapter5-2-1/src/main/java/com/didispace/HelloApplication.java new file mode 100644 index 00000000..bcc80ab6 --- /dev/null +++ b/1.x/Chapter5-2-1/src/main/java/com/didispace/HelloApplication.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/RabbitConfig.java b/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/RabbitConfig.java new file mode 100644 index 00000000..fb66b352 --- /dev/null +++ b/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/RabbitConfig.java @@ -0,0 +1,20 @@ +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"); + } + +} diff --git a/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Receiver.java b/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Receiver.java new file mode 100644 index 00000000..6e014023 --- /dev/null +++ b/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Receiver.java @@ -0,0 +1,24 @@ +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); + } + +} diff --git a/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Sender.java b/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Sender.java new file mode 100644 index 00000000..93afe3af --- /dev/null +++ b/1.x/Chapter5-2-1/src/main/java/com/didispace/rabbit/Sender.java @@ -0,0 +1,22 @@ +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); + } + +} \ No newline at end of file diff --git a/1.x/Chapter5-2-1/src/main/resources/application.properties b/1.x/Chapter5-2-1/src/main/resources/application.properties new file mode 100644 index 00000000..0e1db366 --- /dev/null +++ b/1.x/Chapter5-2-1/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.application.name=rabbitmq-hello + +spring.rabbitmq.host=localhost +spring.rabbitmq.port=5672 +spring.rabbitmq.username=springcloud +spring.rabbitmq.password=123456 diff --git a/1.x/Chapter5-2-1/src/test/java/com/didispace/HelloApplicationTests.java b/1.x/Chapter5-2-1/src/test/java/com/didispace/HelloApplicationTests.java new file mode 100644 index 00000000..82f32c2c --- /dev/null +++ b/1.x/Chapter5-2-1/src/test/java/com/didispace/HelloApplicationTests.java @@ -0,0 +1,22 @@ +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(); + } + +} diff --git a/1.x/Chapter6-1-1/pom.xml b/1.x/Chapter6-1-1/pom.xml new file mode 100644 index 00000000..ef3fd659 --- /dev/null +++ b/1.x/Chapter6-1-1/pom.xml @@ -0,0 +1,46 @@ + + + 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 + + + + diff --git a/1.x/Chapter6-1-1/src/main/java/com/didispace/Application.java b/1.x/Chapter6-1-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..34c59f48 --- /dev/null +++ b/1.x/Chapter6-1-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,26 @@ +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); + } + +} diff --git a/1.x/Chapter6-1-1/src/main/java/com/didispace/EventConfig.java b/1.x/Chapter6-1-1/src/main/java/com/didispace/EventConfig.java new file mode 100644 index 00000000..9ef447a2 --- /dev/null +++ b/1.x/Chapter6-1-1/src/main/java/com/didispace/EventConfig.java @@ -0,0 +1,40 @@ +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("用户已收货,订单完成"); + } + +} \ No newline at end of file diff --git a/1.x/Chapter6-1-1/src/main/java/com/didispace/Events.java b/1.x/Chapter6-1-1/src/main/java/com/didispace/Events.java new file mode 100644 index 00000000..3d67888d --- /dev/null +++ b/1.x/Chapter6-1-1/src/main/java/com/didispace/Events.java @@ -0,0 +1,6 @@ +package com.didispace; + +public enum Events { + PAY, // 支付 + RECEIVE // 收货 +} \ No newline at end of file diff --git a/1.x/Chapter6-1-1/src/main/java/com/didispace/StateMachineConfig.java b/1.x/Chapter6-1-1/src/main/java/com/didispace/StateMachineConfig.java new file mode 100644 index 00000000..919004ca --- /dev/null +++ b/1.x/Chapter6-1-1/src/main/java/com/didispace/StateMachineConfig.java @@ -0,0 +1,82 @@ +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; +// } +// } +// +// }; +// } + +} diff --git a/1.x/Chapter6-1-1/src/main/java/com/didispace/States.java b/1.x/Chapter6-1-1/src/main/java/com/didispace/States.java new file mode 100644 index 00000000..4adbb0e8 --- /dev/null +++ b/1.x/Chapter6-1-1/src/main/java/com/didispace/States.java @@ -0,0 +1,7 @@ +package com.didispace; + +public enum States { + UNPAID, // 待支付 + WAITING_FOR_RECEIVE, // 待收货 + DONE // 结束 +} diff --git a/1.x/Chapter6-1-1/src/main/resources/application.properties b/1.x/Chapter6-1-1/src/main/resources/application.properties new file mode 100644 index 00000000..a60671a2 --- /dev/null +++ b/1.x/Chapter6-1-1/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.application.name=statemachine + diff --git a/1.x/Chapter6-2-1/pom.xml b/1.x/Chapter6-2-1/pom.xml new file mode 100644 index 00000000..c5b07cf7 --- /dev/null +++ b/1.x/Chapter6-2-1/pom.xml @@ -0,0 +1,69 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/1.x/Chapter6-2-1/src/main/java/com/didispace/Application.java b/1.x/Chapter6-2-1/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..f7a9e16e --- /dev/null +++ b/1.x/Chapter6-2-1/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/1.x/Chapter6-2-1/src/main/java/com/didispace/web/HelloController.java b/1.x/Chapter6-2-1/src/main/java/com/didispace/web/HelloController.java new file mode 100644 index 00000000..58c767ef --- /dev/null +++ b/1.x/Chapter6-2-1/src/main/java/com/didispace/web/HelloController.java @@ -0,0 +1,21 @@ +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"; + } + +} \ No newline at end of file diff --git a/1.x/Chapter6-2-1/src/main/resources/application.properties b/1.x/Chapter6-2-1/src/main/resources/application.properties new file mode 100644 index 00000000..c9508007 --- /dev/null +++ b/1.x/Chapter6-2-1/src/main/resources/application.properties @@ -0,0 +1 @@ +#management.info.git.mode=full \ No newline at end of file diff --git a/1.x/Chapter6-2-1/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter6-2-1/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..62cd38ea --- /dev/null +++ b/1.x/Chapter6-2-1/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,22 @@ +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 { + + } + +} diff --git a/1.x/Chapter9-1-1/compute-service/pom.xml b/1.x/Chapter9-1-1/compute-service/pom.xml new file mode 100644 index 00000000..04ef83d0 --- /dev/null +++ b/1.x/Chapter9-1-1/compute-service/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java b/1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java new file mode 100755 index 00000000..cc306350 --- /dev/null +++ b/1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/web/ComputeController.java b/1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/web/ComputeController.java new file mode 100755 index 00000000..06dff1f8 --- /dev/null +++ b/1.x/Chapter9-1-1/compute-service/src/main/java/com/didispace/web/ComputeController.java @@ -0,0 +1,28 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-1/compute-service/src/main/resources/application.properties b/1.x/Chapter9-1-1/compute-service/src/main/resources/application.properties new file mode 100644 index 00000000..c14fe52a --- /dev/null +++ b/1.x/Chapter9-1-1/compute-service/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.application.name=compute-service + +server.port=2222 + +eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ + diff --git a/1.x/Chapter9-1-1/compute-service/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-1-1/compute-service/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..a2f42803 --- /dev/null +++ b/1.x/Chapter9-1-1/compute-service/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,40 @@ +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"))); + } + +} diff --git a/1.x/Chapter9-1-1/eureka-server/pom.xml b/1.x/Chapter9-1-1/eureka-server/pom.xml new file mode 100644 index 00000000..3f01c311 --- /dev/null +++ b/1.x/Chapter9-1-1/eureka-server/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-1/eureka-server/src/main/java/com/didispace/Application.java b/1.x/Chapter9-1-1/eureka-server/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..414607dd --- /dev/null +++ b/1.x/Chapter9-1-1/eureka-server/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-1/eureka-server/src/main/resources/application.properties b/1.x/Chapter9-1-1/eureka-server/src/main/resources/application.properties new file mode 100644 index 00000000..8dad7230 --- /dev/null +++ b/1.x/Chapter9-1-1/eureka-server/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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/ \ No newline at end of file diff --git a/1.x/Chapter9-1-2/eureka-feign/pom.xml b/1.x/Chapter9-1-2/eureka-feign/pom.xml new file mode 100644 index 00000000..d7c050de --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-feign/pom.xml @@ -0,0 +1,68 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/FeignApplication.java b/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/FeignApplication.java new file mode 100755 index 00000000..9e1228f5 --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/FeignApplication.java @@ -0,0 +1,17 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java b/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java new file mode 100644 index 00000000..c804ffac --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java @@ -0,0 +1,14 @@ +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); + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java b/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java new file mode 100755 index 00000000..7876fbfa --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java @@ -0,0 +1,20 @@ +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); + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-2/eureka-feign/src/main/resources/application.properties b/1.x/Chapter9-1-2/eureka-feign/src/main/resources/application.properties new file mode 100755 index 00000000..d9d2128c --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-feign/src/main/resources/application.properties @@ -0,0 +1,5 @@ +spring.application.name=feign-consumer +server.port=3333 + +eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ + diff --git a/1.x/Chapter9-1-2/eureka-ribbon/pom.xml b/1.x/Chapter9-1-2/eureka-ribbon/pom.xml new file mode 100644 index 00000000..3208a14d --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-ribbon/pom.xml @@ -0,0 +1,68 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java b/1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java new file mode 100755 index 00000000..6a4a7556 --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java @@ -0,0 +1,24 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java b/1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java new file mode 100755 index 00000000..55af6003 --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java @@ -0,0 +1,21 @@ +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(); + } + + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-2/eureka-ribbon/src/main/resources/application.properties b/1.x/Chapter9-1-2/eureka-ribbon/src/main/resources/application.properties new file mode 100755 index 00000000..d819480d --- /dev/null +++ b/1.x/Chapter9-1-2/eureka-ribbon/src/main/resources/application.properties @@ -0,0 +1,5 @@ +spring.application.name=ribbon-consumer +server.port=3333 + +eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ + diff --git a/1.x/Chapter9-1-3/compute-service/pom.xml b/1.x/Chapter9-1-3/compute-service/pom.xml new file mode 100644 index 00000000..04ef83d0 --- /dev/null +++ b/1.x/Chapter9-1-3/compute-service/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java b/1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java new file mode 100644 index 00000000..cc306350 --- /dev/null +++ b/1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/ComputeServiceApplication.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/web/ComputeController.java b/1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/web/ComputeController.java new file mode 100644 index 00000000..06dff1f8 --- /dev/null +++ b/1.x/Chapter9-1-3/compute-service/src/main/java/com/didispace/web/ComputeController.java @@ -0,0 +1,28 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-3/compute-service/src/main/resources/application.properties b/1.x/Chapter9-1-3/compute-service/src/main/resources/application.properties new file mode 100644 index 00000000..c14fe52a --- /dev/null +++ b/1.x/Chapter9-1-3/compute-service/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.application.name=compute-service + +server.port=2222 + +eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ + diff --git a/1.x/Chapter9-1-3/compute-service/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-1-3/compute-service/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..a2f42803 --- /dev/null +++ b/1.x/Chapter9-1-3/compute-service/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,40 @@ +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"))); + } + +} diff --git a/1.x/Chapter9-1-3/eureka-feign/pom.xml b/1.x/Chapter9-1-3/eureka-feign/pom.xml new file mode 100644 index 00000000..49721596 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-feign/pom.xml @@ -0,0 +1,72 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/FeignApplication.java b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/FeignApplication.java new file mode 100644 index 00000000..9e1228f5 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/FeignApplication.java @@ -0,0 +1,17 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java new file mode 100644 index 00000000..41cae97d --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClient.java @@ -0,0 +1,14 @@ +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); + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClientHystrix.java b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClientHystrix.java new file mode 100644 index 00000000..541aa845 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/service/ComputeClientHystrix.java @@ -0,0 +1,14 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java new file mode 100644 index 00000000..7876fbfa --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-feign/src/main/java/com/didispace/web/ConsumerController.java @@ -0,0 +1,20 @@ +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); + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-ribbon/pom.xml b/1.x/Chapter9-1-3/eureka-ribbon/pom.xml new file mode 100644 index 00000000..f595d543 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-ribbon/pom.xml @@ -0,0 +1,72 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java b/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java new file mode 100644 index 00000000..6ac542cb --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/RibbonApplication.java @@ -0,0 +1,26 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/service/ComputeService.java b/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/service/ComputeService.java new file mode 100644 index 00000000..5766be5a --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/service/ComputeService.java @@ -0,0 +1,23 @@ +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"; + } + +} diff --git a/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java b/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java new file mode 100644 index 00000000..276c9a99 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-ribbon/src/main/java/com/didispace/web/ConsumerController.java @@ -0,0 +1,24 @@ +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(); + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-server/pom.xml b/1.x/Chapter9-1-3/eureka-server/pom.xml new file mode 100644 index 00000000..3f01c311 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-server/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-3/eureka-server/src/main/java/com/didispace/Application.java b/1.x/Chapter9-1-3/eureka-server/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..414607dd --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-server/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-3/eureka-server/src/main/resources/application.properties b/1.x/Chapter9-1-3/eureka-server/src/main/resources/application.properties new file mode 100644 index 00000000..8dad7230 --- /dev/null +++ b/1.x/Chapter9-1-3/eureka-server/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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/ \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-client/pom.xml b/1.x/Chapter9-1-4/config-client/pom.xml new file mode 100644 index 00000000..5cfdb391 --- /dev/null +++ b/1.x/Chapter9-1-4/config-client/pom.xml @@ -0,0 +1,67 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/Application.java b/1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..d956eafd --- /dev/null +++ b/1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/web/TestController.java b/1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/web/TestController.java new file mode 100644 index 00000000..f8b8095f --- /dev/null +++ b/1.x/Chapter9-1-4/config-client/src/main/java/com/didispace/web/TestController.java @@ -0,0 +1,29 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-client/src/main/resources/bootstrap.properties b/1.x/Chapter9-1-4/config-client/src/main/resources/bootstrap.properties new file mode 100644 index 00000000..f42ca34b --- /dev/null +++ b/1.x/Chapter9-1-4/config-client/src/main/resources/bootstrap.properties @@ -0,0 +1,10 @@ +spring.application.name=didispace +spring.cloud.config.profile=dev +spring.cloud.config.uri=http://localhost:7001/ + +server.port=7002 + + + + + diff --git a/1.x/Chapter9-1-4/config-repo/didispace-dev.properties b/1.x/Chapter9-1-4/config-repo/didispace-dev.properties new file mode 100644 index 00000000..208e1304 --- /dev/null +++ b/1.x/Chapter9-1-4/config-repo/didispace-dev.properties @@ -0,0 +1 @@ +from=git-dev-1.0 \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-repo/didispace-prod.properties b/1.x/Chapter9-1-4/config-repo/didispace-prod.properties new file mode 100644 index 00000000..e982d251 --- /dev/null +++ b/1.x/Chapter9-1-4/config-repo/didispace-prod.properties @@ -0,0 +1 @@ +from=git-prod-1.0 \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-repo/didispace-test.properties b/1.x/Chapter9-1-4/config-repo/didispace-test.properties new file mode 100644 index 00000000..c8892f13 --- /dev/null +++ b/1.x/Chapter9-1-4/config-repo/didispace-test.properties @@ -0,0 +1 @@ +from=git-test-1.0 \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-repo/didispace.properties b/1.x/Chapter9-1-4/config-repo/didispace.properties new file mode 100644 index 00000000..11d146d2 --- /dev/null +++ b/1.x/Chapter9-1-4/config-repo/didispace.properties @@ -0,0 +1 @@ +from=git-default-1.0 diff --git a/1.x/Chapter9-1-4/config-server/pom.xml b/1.x/Chapter9-1-4/config-server/pom.xml new file mode 100644 index 00000000..379aa99d --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-server/src/main/java/com/didispace/Application.java b/1.x/Chapter9-1-4/config-server/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..a2e140c3 --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-4/config-server/src/main/resources/application.properties b/1.x/Chapter9-1-4/config-server/src/main/resources/application.properties new file mode 100644 index 00000000..4157fdd4 --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/src/main/resources/application.properties @@ -0,0 +1,15 @@ +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 + + + + diff --git a/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-dev.properties b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-dev.properties new file mode 100644 index 00000000..723b404a --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-dev.properties @@ -0,0 +1 @@ +from=local-dev \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-prod.properties b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-prod.properties new file mode 100644 index 00000000..7be43560 --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-prod.properties @@ -0,0 +1 @@ +from=local-prod \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-test.properties b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-test.properties new file mode 100644 index 00000000..fc224763 --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace-test.properties @@ -0,0 +1 @@ +from=local-test \ No newline at end of file diff --git a/1.x/Chapter9-1-4/config-server/src/main/resources/didispace.properties b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace.properties new file mode 100644 index 00000000..11e023a7 --- /dev/null +++ b/1.x/Chapter9-1-4/config-server/src/main/resources/didispace.properties @@ -0,0 +1 @@ +from=local \ No newline at end of file diff --git a/1.x/Chapter9-1-5/api-gateway/pom.xml b/1.x/Chapter9-1-5/api-gateway/pom.xml new file mode 100644 index 00000000..5ad32b66 --- /dev/null +++ b/1.x/Chapter9-1-5/api-gateway/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/Application.java b/1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..e0416950 --- /dev/null +++ b/1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/Application.java @@ -0,0 +1,22 @@ +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(); + } + +} diff --git a/1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/filter/AccessFilter.java b/1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/filter/AccessFilter.java new file mode 100644 index 00000000..489e6aaf --- /dev/null +++ b/1.x/Chapter9-1-5/api-gateway/src/main/java/com/didispace/filter/AccessFilter.java @@ -0,0 +1,47 @@ +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; + } + +} diff --git a/1.x/Chapter9-1-5/api-gateway/src/main/resources/application.properties b/1.x/Chapter9-1-5/api-gateway/src/main/resources/application.properties new file mode 100644 index 00000000..1f70d666 --- /dev/null +++ b/1.x/Chapter9-1-5/api-gateway/src/main/resources/application.properties @@ -0,0 +1,15 @@ +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/ \ No newline at end of file diff --git a/1.x/Chapter9-1-5/eureka-server/pom.xml b/1.x/Chapter9-1-5/eureka-server/pom.xml new file mode 100644 index 00000000..3f01c311 --- /dev/null +++ b/1.x/Chapter9-1-5/eureka-server/pom.xml @@ -0,0 +1,62 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-5/eureka-server/src/main/java/com/didispace/Application.java b/1.x/Chapter9-1-5/eureka-server/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..414607dd --- /dev/null +++ b/1.x/Chapter9-1-5/eureka-server/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-5/eureka-server/src/main/resources/application.properties b/1.x/Chapter9-1-5/eureka-server/src/main/resources/application.properties new file mode 100644 index 00000000..8dad7230 --- /dev/null +++ b/1.x/Chapter9-1-5/eureka-server/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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/ \ No newline at end of file diff --git a/1.x/Chapter9-1-5/service-A/pom.xml b/1.x/Chapter9-1-5/service-A/pom.xml new file mode 100644 index 00000000..d9701013 --- /dev/null +++ b/1.x/Chapter9-1-5/service-A/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/ComputeServiceApplication.java b/1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/ComputeServiceApplication.java new file mode 100644 index 00000000..cc306350 --- /dev/null +++ b/1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/ComputeServiceApplication.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/web/ComputeController.java b/1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/web/ComputeController.java new file mode 100644 index 00000000..6024f1cd --- /dev/null +++ b/1.x/Chapter9-1-5/service-A/src/main/java/com/didispace/web/ComputeController.java @@ -0,0 +1,28 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-5/service-A/src/main/resources/application.properties b/1.x/Chapter9-1-5/service-A/src/main/resources/application.properties new file mode 100644 index 00000000..c212856f --- /dev/null +++ b/1.x/Chapter9-1-5/service-A/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.application.name=service-A + +server.port=2222 + +eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ + diff --git a/1.x/Chapter9-1-5/service-A/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-1-5/service-A/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..08cfadd9 --- /dev/null +++ b/1.x/Chapter9-1-5/service-A/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,37 @@ +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 { + } + +} diff --git a/1.x/Chapter9-1-5/service-B/pom.xml b/1.x/Chapter9-1-5/service-B/pom.xml new file mode 100644 index 00000000..3420bdfd --- /dev/null +++ b/1.x/Chapter9-1-5/service-B/pom.xml @@ -0,0 +1,61 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/ComputeServiceApplication.java b/1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/ComputeServiceApplication.java new file mode 100644 index 00000000..cc306350 --- /dev/null +++ b/1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/ComputeServiceApplication.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/web/ComputeController.java b/1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/web/ComputeController.java new file mode 100644 index 00000000..31af894d --- /dev/null +++ b/1.x/Chapter9-1-5/service-B/src/main/java/com/didispace/web/ComputeController.java @@ -0,0 +1,28 @@ +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; + } + +} \ No newline at end of file diff --git a/1.x/Chapter9-1-5/service-B/src/main/resources/application.properties b/1.x/Chapter9-1-5/service-B/src/main/resources/application.properties new file mode 100644 index 00000000..a9069020 --- /dev/null +++ b/1.x/Chapter9-1-5/service-B/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.application.name=service-B + +server.port=3333 + +eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ + diff --git a/1.x/Chapter9-1-5/service-B/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-1-5/service-B/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..14124aca --- /dev/null +++ b/1.x/Chapter9-1-5/service-B/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,31 @@ +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 { + } + +} diff --git a/1.x/Chapter9-2-1/compute-service/pom.xml b/1.x/Chapter9-2-1/compute-service/pom.xml new file mode 100644 index 00000000..89aed4d7 --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/pom.xml @@ -0,0 +1,83 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/Application.java b/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..4742e524 --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/Application.java @@ -0,0 +1,30 @@ +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(); + } + +} diff --git a/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/ComputeService.java b/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/ComputeService.java new file mode 100644 index 00000000..327ab162 --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/ComputeService.java @@ -0,0 +1,10 @@ +package com.didispace.service; + +/** + * Created by zhaiyc on 2016/7/14. + */ +public interface ComputeService { + + Integer add(int a, int b); + +} diff --git a/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java b/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java new file mode 100644 index 00000000..30278596 --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java @@ -0,0 +1,15 @@ +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; + } + +} diff --git a/1.x/Chapter9-2-1/compute-service/src/main/resources/application.properties b/1.x/Chapter9-2-1/compute-service/src/main/resources/application.properties new file mode 100644 index 00000000..27fa322f --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/src/main/resources/application.properties @@ -0,0 +1,4 @@ +#ZooKeeper +dubbo.registry.address=localhost:2181 + +logging.level.root=DEBUG \ No newline at end of file diff --git a/1.x/Chapter9-2-1/compute-service/src/main/resources/dubbo.xml b/1.x/Chapter9-2-1/compute-service/src/main/resources/dubbo.xml new file mode 100644 index 00000000..02491d79 --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/src/main/resources/dubbo.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-1/compute-service/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-2-1/compute-service/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..3ee62300 --- /dev/null +++ b/1.x/Chapter9-2-1/compute-service/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,22 @@ +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 { + } + +} diff --git a/1.x/Chapter9-2-1/consumer/pom.xml b/1.x/Chapter9-2-1/consumer/pom.xml new file mode 100644 index 00000000..7b35a9d4 --- /dev/null +++ b/1.x/Chapter9-2-1/consumer/pom.xml @@ -0,0 +1,83 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/Application.java b/1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..017ffc60 --- /dev/null +++ b/1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/Application.java @@ -0,0 +1,20 @@ +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); + } + +} diff --git a/1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/service/ComputeService.java b/1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/service/ComputeService.java new file mode 100644 index 00000000..327ab162 --- /dev/null +++ b/1.x/Chapter9-2-1/consumer/src/main/java/com/didispace/service/ComputeService.java @@ -0,0 +1,10 @@ +package com.didispace.service; + +/** + * Created by zhaiyc on 2016/7/14. + */ +public interface ComputeService { + + Integer add(int a, int b); + +} diff --git a/1.x/Chapter9-2-1/consumer/src/main/resources/application.properties b/1.x/Chapter9-2-1/consumer/src/main/resources/application.properties new file mode 100644 index 00000000..c9ce0270 --- /dev/null +++ b/1.x/Chapter9-2-1/consumer/src/main/resources/application.properties @@ -0,0 +1,5 @@ +#ZooKeeper +dubbo.registry.address=localhost:2181 + + +logging.level.root=DEBUG \ No newline at end of file diff --git a/1.x/Chapter9-2-1/consumer/src/main/resources/dubbo.xml b/1.x/Chapter9-2-1/consumer/src/main/resources/dubbo.xml new file mode 100644 index 00000000..4760bfaf --- /dev/null +++ b/1.x/Chapter9-2-1/consumer/src/main/resources/dubbo.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-1/consumer/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-2-1/consumer/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..7b9c59e9 --- /dev/null +++ b/1.x/Chapter9-2-1/consumer/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,24 @@ +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)); + } + +} diff --git a/1.x/Chapter9-2-2/compute-service/compute-api-server/pom.xml b/1.x/Chapter9-2-2/compute-service/compute-api-server/pom.xml new file mode 100644 index 00000000..7a0b4988 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api-server/pom.xml @@ -0,0 +1,93 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/Application.java b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..4742e524 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/Application.java @@ -0,0 +1,30 @@ +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(); + } + +} diff --git a/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java new file mode 100644 index 00000000..30278596 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java @@ -0,0 +1,15 @@ +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; + } + +} diff --git a/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/application.properties b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/application.properties new file mode 100644 index 00000000..27fa322f --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/application.properties @@ -0,0 +1,4 @@ +#ZooKeeper +dubbo.registry.address=localhost:2181 + +logging.level.root=DEBUG \ No newline at end of file diff --git a/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/dubbo.xml b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/dubbo.xml new file mode 100644 index 00000000..02491d79 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/main/resources/dubbo.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-2/compute-service/compute-api-server/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..3ee62300 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api-server/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,22 @@ +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 { + } + +} diff --git a/1.x/Chapter9-2-2/compute-service/compute-api/pom.xml b/1.x/Chapter9-2-2/compute-service/compute-api/pom.xml new file mode 100644 index 00000000..0a2049c4 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api/pom.xml @@ -0,0 +1,17 @@ + + + + 4.0.0 + + + com.didispace + compute-service + 1.0-SNAPSHOT + + + compute-api + compute-api + jar + + \ No newline at end of file diff --git a/1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/ComputeService.java b/1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/ComputeService.java new file mode 100644 index 00000000..327ab162 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/ComputeService.java @@ -0,0 +1,10 @@ +package com.didispace.service; + +/** + * Created by zhaiyc on 2016/7/14. + */ +public interface ComputeService { + + Integer add(int a, int b); + +} diff --git a/1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java b/1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java new file mode 100644 index 00000000..30278596 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/compute-api/src/main/java/com/didispace/service/impl/ComputeServiceImpl.java @@ -0,0 +1,15 @@ +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; + } + +} diff --git a/1.x/Chapter9-2-2/compute-service/pom.xml b/1.x/Chapter9-2-2/compute-service/pom.xml new file mode 100644 index 00000000..3d8d6c92 --- /dev/null +++ b/1.x/Chapter9-2-2/compute-service/pom.xml @@ -0,0 +1,26 @@ + + + + 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 + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-2/consumer/pom.xml b/1.x/Chapter9-2-2/consumer/pom.xml new file mode 100644 index 00000000..e3630d29 --- /dev/null +++ b/1.x/Chapter9-2-2/consumer/pom.xml @@ -0,0 +1,95 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-2/consumer/src/main/java/com/didispace/Application.java b/1.x/Chapter9-2-2/consumer/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..945f495a --- /dev/null +++ b/1.x/Chapter9-2-2/consumer/src/main/java/com/didispace/Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/1.x/Chapter9-2-2/consumer/src/main/resources/application.properties b/1.x/Chapter9-2-2/consumer/src/main/resources/application.properties new file mode 100644 index 00000000..714b9088 --- /dev/null +++ b/1.x/Chapter9-2-2/consumer/src/main/resources/application.properties @@ -0,0 +1,5 @@ +#ZooKeeper +dubbo.registry.address=localhost:2181 + + +logging.level.root=INFO \ No newline at end of file diff --git a/1.x/Chapter9-2-2/consumer/src/main/resources/dubbo.xml b/1.x/Chapter9-2-2/consumer/src/main/resources/dubbo.xml new file mode 100644 index 00000000..4760bfaf --- /dev/null +++ b/1.x/Chapter9-2-2/consumer/src/main/resources/dubbo.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/1.x/Chapter9-2-2/consumer/src/test/java/com/didispace/ApplicationTests.java b/1.x/Chapter9-2-2/consumer/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..4f5c3d5a --- /dev/null +++ b/1.x/Chapter9-2-2/consumer/src/test/java/com/didispace/ApplicationTests.java @@ -0,0 +1,24 @@ +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)); + } + +} diff --git a/1.x/README.md b/1.x/README.md new file mode 100644 index 00000000..0fdaf52c --- /dev/null +++ b/1.x/README.md @@ -0,0 +1,124 @@ +该目录下为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基础教程 + +## 我的公众号 + + + + diff --git a/1.x/README_zh.md b/1.x/README_zh.md new file mode 100644 index 00000000..0fdaf52c --- /dev/null +++ b/1.x/README_zh.md @@ -0,0 +1,124 @@ +该目录下为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基础教程 + +## 我的公众号 + + + + diff --git a/2.x/README.md b/2.x/README.md new file mode 100644 index 00000000..af580d69 --- /dev/null +++ b/2.x/README.md @@ -0,0 +1,184 @@ +# 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` \ No newline at end of file diff --git a/2.x/README_zh.md b/2.x/README_zh.md new file mode 100644 index 00000000..70612143 --- /dev/null +++ b/2.x/README_zh.md @@ -0,0 +1,202 @@ +# 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` \ No newline at end of file diff --git a/2.x/chapter1-1/.gitignore b/2.x/chapter1-1/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter1-1/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter1-1/pom.xml b/2.x/chapter1-1/pom.xml new file mode 100644 index 00000000..d4e872a6 --- /dev/null +++ b/2.x/chapter1-1/pom.xml @@ -0,0 +1,43 @@ + + + 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 + + + + + diff --git a/2.x/chapter1-1/src/main/java/com/didispace/chapter11/Chapter11Application.java b/2.x/chapter1-1/src/main/java/com/didispace/chapter11/Chapter11Application.java new file mode 100644 index 00000000..17cd4a7c --- /dev/null +++ b/2.x/chapter1-1/src/main/java/com/didispace/chapter11/Chapter11Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter1-1/src/main/java/com/didispace/chapter11/HelloController.java b/2.x/chapter1-1/src/main/java/com/didispace/chapter11/HelloController.java new file mode 100644 index 00000000..d19b5ef6 --- /dev/null +++ b/2.x/chapter1-1/src/main/java/com/didispace/chapter11/HelloController.java @@ -0,0 +1,14 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter1-1/src/main/resources/application.properties b/2.x/chapter1-1/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/2.x/chapter1-1/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/2.x/chapter1-1/src/test/java/com/didispace/chapter11/Chapter11ApplicationTests.java b/2.x/chapter1-1/src/test/java/com/didispace/chapter11/Chapter11ApplicationTests.java new file mode 100644 index 00000000..e39db87a --- /dev/null +++ b/2.x/chapter1-1/src/test/java/com/didispace/chapter11/Chapter11ApplicationTests.java @@ -0,0 +1,33 @@ +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"))); + } + +} diff --git a/2.x/chapter1-2/.gitignore b/2.x/chapter1-2/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter1-2/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter1-2/pom.xml b/2.x/chapter1-2/pom.xml new file mode 100644 index 00000000..4bee1018 --- /dev/null +++ b/2.x/chapter1-2/pom.xml @@ -0,0 +1,43 @@ + + + 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 + + + + + diff --git a/2.x/chapter1-2/src/main/java/com/didispace/chapter12/Chapter12Application.java b/2.x/chapter1-2/src/main/java/com/didispace/chapter12/Chapter12Application.java new file mode 100644 index 00000000..135b7e80 --- /dev/null +++ b/2.x/chapter1-2/src/main/java/com/didispace/chapter12/Chapter12Application.java @@ -0,0 +1,29 @@ +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; + } + + } + +} diff --git a/2.x/chapter1-2/src/main/resources/application.yaml b/2.x/chapter1-2/src/main/resources/application.yaml new file mode 100644 index 00000000..ad1b68d1 --- /dev/null +++ b/2.x/chapter1-2/src/main/resources/application.yaml @@ -0,0 +1,31 @@ +# 默认激活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 \ No newline at end of file diff --git a/2.x/chapter1-3/.gitignore b/2.x/chapter1-3/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter1-3/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter1-3/pom.xml b/2.x/chapter1-3/pom.xml new file mode 100644 index 00000000..93b6ec3a --- /dev/null +++ b/2.x/chapter1-3/pom.xml @@ -0,0 +1,49 @@ + + + 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 + + + + + diff --git a/2.x/chapter1-3/src/main/java/com/didispace/chapter13/Chapter13Application.java b/2.x/chapter1-3/src/main/java/com/didispace/chapter13/Chapter13Application.java new file mode 100644 index 00000000..7db17464 --- /dev/null +++ b/2.x/chapter1-3/src/main/java/com/didispace/chapter13/Chapter13Application.java @@ -0,0 +1,37 @@ +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 ""; + } + + } + +} diff --git a/2.x/chapter1-3/src/main/resources/application.yaml b/2.x/chapter1-3/src/main/resources/application.yaml new file mode 100644 index 00000000..70e7a52e --- /dev/null +++ b/2.x/chapter1-3/src/main/resources/application.yaml @@ -0,0 +1,61 @@ +# 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 diff --git a/2.x/chapter1-4/.gitignore b/2.x/chapter1-4/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter1-4/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter1-4/pom.xml b/2.x/chapter1-4/pom.xml new file mode 100644 index 00000000..5bbd4008 --- /dev/null +++ b/2.x/chapter1-4/pom.xml @@ -0,0 +1,52 @@ + + + 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 + + + + + diff --git a/2.x/chapter1-4/src/main/java/com/didispace/chapter14/Chapter14Application.java b/2.x/chapter1-4/src/main/java/com/didispace/chapter14/Chapter14Application.java new file mode 100644 index 00000000..ff6b7d72 --- /dev/null +++ b/2.x/chapter1-4/src/main/java/com/didispace/chapter14/Chapter14Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter1-4/src/main/java/com/didispace/chapter14/DidiProperties.java b/2.x/chapter1-4/src/main/java/com/didispace/chapter14/DidiProperties.java new file mode 100644 index 00000000..d283aef1 --- /dev/null +++ b/2.x/chapter1-4/src/main/java/com/didispace/chapter14/DidiProperties.java @@ -0,0 +1,17 @@ +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; + +} diff --git a/2.x/chapter1-4/src/main/java/com/didispace/chapter14/HelloController.java b/2.x/chapter1-4/src/main/java/com/didispace/chapter14/HelloController.java new file mode 100644 index 00000000..084af5b8 --- /dev/null +++ b/2.x/chapter1-4/src/main/java/com/didispace/chapter14/HelloController.java @@ -0,0 +1,14 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter1-4/src/main/resources/application.properties b/2.x/chapter1-4/src/main/resources/application.properties new file mode 100644 index 00000000..20da7c87 --- /dev/null +++ b/2.x/chapter1-4/src/main/resources/application.properties @@ -0,0 +1,3 @@ + +com.didispace.from=didi + diff --git a/2.x/chapter1-5/.gitignore b/2.x/chapter1-5/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter1-5/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter1-5/pom.xml b/2.x/chapter1-5/pom.xml new file mode 100644 index 00000000..a9c25152 --- /dev/null +++ b/2.x/chapter1-5/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + diff --git a/2.x/chapter1-5/src/main/java/com/didispace/chapter15/Chapter15Application.java b/2.x/chapter1-5/src/main/java/com/didispace/chapter15/Chapter15Application.java new file mode 100644 index 00000000..6b0c79d6 --- /dev/null +++ b/2.x/chapter1-5/src/main/java/com/didispace/chapter15/Chapter15Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter1-5/src/main/resources/application.properties b/2.x/chapter1-5/src/main/resources/application.properties new file mode 100644 index 00000000..b5780fe0 --- /dev/null +++ b/2.x/chapter1-5/src/main/resources/application.properties @@ -0,0 +1,10 @@ + +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=) \ No newline at end of file diff --git a/2.x/chapter1-5/src/test/java/com/didispace/chapter15/PropertiesTest.java b/2.x/chapter1-5/src/test/java/com/didispace/chapter15/PropertiesTest.java new file mode 100644 index 00000000..db8ff86d --- /dev/null +++ b/2.x/chapter1-5/src/test/java/com/didispace/chapter15/PropertiesTest.java @@ -0,0 +1,21 @@ +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); + } + +} diff --git a/2.x/chapter2-1/.gitignore b/2.x/chapter2-1/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter2-1/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter2-1/pom.xml b/2.x/chapter2-1/pom.xml new file mode 100644 index 00000000..3b306388 --- /dev/null +++ b/2.x/chapter2-1/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter2-1/src/main/java/com/didispace/chapter21/Chapter21Application.java b/2.x/chapter2-1/src/main/java/com/didispace/chapter21/Chapter21Application.java new file mode 100644 index 00000000..936e8024 --- /dev/null +++ b/2.x/chapter2-1/src/main/java/com/didispace/chapter21/Chapter21Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter2-1/src/main/java/com/didispace/chapter21/User.java b/2.x/chapter2-1/src/main/java/com/didispace/chapter21/User.java new file mode 100644 index 00000000..1f8749c1 --- /dev/null +++ b/2.x/chapter2-1/src/main/java/com/didispace/chapter21/User.java @@ -0,0 +1,12 @@ +package com.didispace.chapter21; + +import lombok.Data; + +@Data +public class User { + + private Long id; + private String name; + private Integer age; + +} \ No newline at end of file diff --git a/2.x/chapter2-1/src/main/java/com/didispace/chapter21/UserController.java b/2.x/chapter2-1/src/main/java/com/didispace/chapter21/UserController.java new file mode 100644 index 00000000..c855f1a9 --- /dev/null +++ b/2.x/chapter2-1/src/main/java/com/didispace/chapter21/UserController.java @@ -0,0 +1,79 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-1/src/main/resources/application.properties b/2.x/chapter2-1/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/2.x/chapter2-1/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/2.x/chapter2-1/src/test/java/com/didispace/chapter21/Chapter21ApplicationTests.java b/2.x/chapter2-1/src/test/java/com/didispace/chapter21/Chapter21ApplicationTests.java new file mode 100644 index 00000000..880d2823 --- /dev/null +++ b/2.x/chapter2-1/src/test/java/com/didispace/chapter21/Chapter21ApplicationTests.java @@ -0,0 +1,79 @@ +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("[]"))); + + } + +} diff --git a/2.x/chapter2-2/.gitignore b/2.x/chapter2-2/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter2-2/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter2-2/pom.xml b/2.x/chapter2-2/pom.xml new file mode 100644 index 00000000..7d31c5eb --- /dev/null +++ b/2.x/chapter2-2/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + diff --git a/2.x/chapter2-2/src/main/java/com/didispace/chapter22/Chapter22Application.java b/2.x/chapter2-2/src/main/java/com/didispace/chapter22/Chapter22Application.java new file mode 100644 index 00000000..cd6963b8 --- /dev/null +++ b/2.x/chapter2-2/src/main/java/com/didispace/chapter22/Chapter22Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter2-2/src/main/java/com/didispace/chapter22/User.java b/2.x/chapter2-2/src/main/java/com/didispace/chapter22/User.java new file mode 100644 index 00000000..1a265300 --- /dev/null +++ b/2.x/chapter2-2/src/main/java/com/didispace/chapter22/User.java @@ -0,0 +1,18 @@ +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; + +} \ No newline at end of file diff --git a/2.x/chapter2-2/src/main/java/com/didispace/chapter22/UserController.java b/2.x/chapter2-2/src/main/java/com/didispace/chapter22/UserController.java new file mode 100644 index 00000000..cc517afb --- /dev/null +++ b/2.x/chapter2-2/src/main/java/com/didispace/chapter22/UserController.java @@ -0,0 +1,56 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-2/src/main/resources/application.properties b/2.x/chapter2-2/src/main/resources/application.properties new file mode 100644 index 00000000..55ec2942 --- /dev/null +++ b/2.x/chapter2-2/src/main/resources/application.properties @@ -0,0 +1,13 @@ + + +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=/** \ No newline at end of file diff --git a/2.x/chapter2-3/.gitignore b/2.x/chapter2-3/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter2-3/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter2-3/pom.xml b/2.x/chapter2-3/pom.xml new file mode 100644 index 00000000..da056f65 --- /dev/null +++ b/2.x/chapter2-3/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + diff --git a/2.x/chapter2-3/src/main/java/com/didispace/chapter23/Chapter23Application.java b/2.x/chapter2-3/src/main/java/com/didispace/chapter23/Chapter23Application.java new file mode 100644 index 00000000..7ecdd42d --- /dev/null +++ b/2.x/chapter2-3/src/main/java/com/didispace/chapter23/Chapter23Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter2-3/src/main/java/com/didispace/chapter23/User.java b/2.x/chapter2-3/src/main/java/com/didispace/chapter23/User.java new file mode 100644 index 00000000..12f85c88 --- /dev/null +++ b/2.x/chapter2-3/src/main/java/com/didispace/chapter23/User.java @@ -0,0 +1,32 @@ +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; + +} \ No newline at end of file diff --git a/2.x/chapter2-3/src/main/java/com/didispace/chapter23/UserController.java b/2.x/chapter2-3/src/main/java/com/didispace/chapter23/UserController.java new file mode 100644 index 00000000..963ac4c4 --- /dev/null +++ b/2.x/chapter2-3/src/main/java/com/didispace/chapter23/UserController.java @@ -0,0 +1,57 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-3/src/main/resources/application.properties b/2.x/chapter2-3/src/main/resources/application.properties new file mode 100644 index 00000000..55ec2942 --- /dev/null +++ b/2.x/chapter2-3/src/main/resources/application.properties @@ -0,0 +1,13 @@ + + +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=/** \ No newline at end of file diff --git a/2.x/chapter2-4/.gitignore b/2.x/chapter2-4/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter2-4/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter2-4/pom.xml b/2.x/chapter2-4/pom.xml new file mode 100644 index 00000000..844ae4d1 --- /dev/null +++ b/2.x/chapter2-4/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + diff --git a/2.x/chapter2-4/src/main/java/com/didispace/chapter24/Chapter24Application.java b/2.x/chapter2-4/src/main/java/com/didispace/chapter24/Chapter24Application.java new file mode 100644 index 00000000..736bc4f3 --- /dev/null +++ b/2.x/chapter2-4/src/main/java/com/didispace/chapter24/Chapter24Application.java @@ -0,0 +1,61 @@ +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"; + } + + } + +} diff --git a/2.x/chapter2-4/src/main/java/com/didispace/chapter24/User.java b/2.x/chapter2-4/src/main/java/com/didispace/chapter24/User.java new file mode 100644 index 00000000..1d13b648 --- /dev/null +++ b/2.x/chapter2-4/src/main/java/com/didispace/chapter24/User.java @@ -0,0 +1,32 @@ +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; + +} \ No newline at end of file diff --git a/2.x/chapter2-4/src/main/java/com/didispace/chapter24/UserController.java b/2.x/chapter2-4/src/main/java/com/didispace/chapter24/UserController.java new file mode 100644 index 00000000..871a2d9b --- /dev/null +++ b/2.x/chapter2-4/src/main/java/com/didispace/chapter24/UserController.java @@ -0,0 +1,57 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-4/src/main/resources/application.properties b/2.x/chapter2-4/src/main/resources/application.properties new file mode 100644 index 00000000..335a5f4b --- /dev/null +++ b/2.x/chapter2-4/src/main/resources/application.properties @@ -0,0 +1,16 @@ + + +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 \ No newline at end of file diff --git a/2.x/chapter2-5/.gitignore b/2.x/chapter2-5/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter2-5/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter2-5/pom.xml b/2.x/chapter2-5/pom.xml new file mode 100644 index 00000000..2b81ca3b --- /dev/null +++ b/2.x/chapter2-5/pom.xml @@ -0,0 +1,102 @@ + + + 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 + + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/definitions.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/definitions.adoc new file mode 100644 index 00000000..3a20e7fb --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/definitions.adoc @@ -0,0 +1,22 @@ + +[[_definitions]] +== Definitions + +[[_user]] +=== User +用户实体 + + +[options="header", cols=".^3,.^11,.^4"] +|=== +|Name|Description|Schema +|**age** + +__optional__|用户年龄|integer (int32) +|**id** + +__optional__|用户编号|integer (int64) +|**name** + +__optional__|用户姓名|string +|=== + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/overview.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/overview.adoc new file mode 100644 index 00000000..4b9eefbf --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/overview.adoc @@ -0,0 +1,38 @@ += 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 + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/paths.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/paths.adoc new file mode 100644 index 00000000..5e9cf92f --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/paths.adoc @@ -0,0 +1,265 @@ + +[[_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 +|=== + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/security.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/security.adoc new file mode 100644 index 00000000..01db83a5 --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated-by-plugin/security.adoc @@ -0,0 +1,13 @@ + +[[_securityscheme]] +== Security + +[[_authorization]] +=== Authorization +[%hardbreaks] +__Type__ : apiKey +__Name__ : TOKEN +__In__ : HEADER + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated/definitions.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated/definitions.adoc new file mode 100644 index 00000000..a739bda5 --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated/definitions.adoc @@ -0,0 +1,22 @@ + +[[_definitions]] +== Definitions + +[[_user]] +=== User +用户实体 + + +[options="header", cols=".^3a,.^11a,.^4a"] +|=== +|Name|Description|Schema +|**age** + +__optional__|用户年龄|integer (int32) +|**id** + +__optional__|用户编号|integer (int64) +|**name** + +__optional__|用户姓名|string +|=== + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated/overview.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated/overview.adoc new file mode 100644 index 00000000..4b9eefbf --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated/overview.adoc @@ -0,0 +1,38 @@ += 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 + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated/paths.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated/paths.adoc new file mode 100644 index 00000000..6fa4471d --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated/paths.adoc @@ -0,0 +1,265 @@ + +[[_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 +|=== + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/generated/security.adoc b/2.x/chapter2-5/src/docs/asciidoc/generated/security.adoc new file mode 100644 index 00000000..01db83a5 --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/generated/security.adoc @@ -0,0 +1,13 @@ + +[[_securityscheme]] +== Security + +[[_authorization]] +=== Authorization +[%hardbreaks] +__Type__ : apiKey +__Name__ : TOKEN +__In__ : HEADER + + + diff --git a/2.x/chapter2-5/src/docs/asciidoc/html/definitions.html b/2.x/chapter2-5/src/docs/asciidoc/html/definitions.html new file mode 100644 index 00000000..1a9a17f8 --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/html/definitions.html @@ -0,0 +1,603 @@ + + + + + + + +Definitions + + + + + + +
+
+

Definitions

+
+
+

User

+
+

用户实体

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionSchema
+

age
+optional

+
+

用户年龄

+
+

integer (int32)

+
+

id
+optional

+
+

用户编号

+
+

integer (int64)

+
+

name
+optional

+
+

用户姓名

+
+

string

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/2.x/chapter2-5/src/docs/asciidoc/html/overview.html b/2.x/chapter2-5/src/docs/asciidoc/html/overview.html new file mode 100644 index 00000000..842077bb --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/html/overview.html @@ -0,0 +1,591 @@ + + + + + + + +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

    +
  • +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/2.x/chapter2-5/src/docs/asciidoc/html/paths.html b/2.x/chapter2-5/src/docs/asciidoc/html/paths.html new file mode 100644 index 00000000..4b3d92d4 --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/html/paths.html @@ -0,0 +1,1379 @@ + + + + + + + +Paths + + + + + + +
+
+

Paths

+
+
+

创建用户

+
+
+
POST /users/
+
+
+
+

Description

+
+

根据User对象创建用户

+
+
+
+

Parameters

+ ++++++ + + + + + + + + + + + + + + + + +
TypeNameDescriptionSchema
+

Body

+
+

user
+required

+
+

user

+
+

User

+
+
+
+

Responses

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP CodeDescriptionSchema
+

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

+ +++++ + + + + + + + + + + + + + + +
TypeNameScopes
+

apiKey

+
+

global

+
+
+
+
+

获取用户列表

+
+
+
GET /users/
+
+
+
+

Responses

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP CodeDescriptionSchema
+

200

+
+

OK

+
+

< User > array

+
+

401

+
+

Unauthorized

+
+

No Content

+
+

403

+
+

Forbidden

+
+

No Content

+
+

404

+
+

Not Found

+
+

No Content

+
+
+
+

Produces

+
+
    +
  • +

    */*

    +
  • +
+
+
+
+

Tags

+
+
    +
  • +

    用户管理

    +
  • +
+
+
+
+

Security

+ +++++ + + + + + + + + + + + + + + +
TypeNameScopes
+

apiKey

+
+

global

+
+
+
+
+

获取用户详细信息

+
+
+
GET /users/{id}
+
+
+
+

Description

+
+

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

+
+
+
+

Parameters

+ ++++++ + + + + + + + + + + + + + + + + +
TypeNameDescriptionSchema
+

Path

+
+

id
+required

+
+

id

+
+

integer (int64)

+
+
+
+

Responses

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP CodeDescriptionSchema
+

200

+
+

OK

+
+

User

+
+

401

+
+

Unauthorized

+
+

No Content

+
+

403

+
+

Forbidden

+
+

No Content

+
+

404

+
+

Not Found

+
+

No Content

+
+
+
+

Produces

+
+
    +
  • +

    */*

    +
  • +
+
+
+
+

Tags

+
+
    +
  • +

    用户管理

    +
  • +
+
+
+
+

Security

+ +++++ + + + + + + + + + + + + + + +
TypeNameScopes
+

apiKey

+
+

global

+
+
+
+
+

更新用户详细信息

+
+
+
PUT /users/{id}
+
+
+
+

Description

+
+

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

+
+
+
+

Parameters

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionSchema
+

Path

+
+

id
+required

+
+

用户编号

+
+

integer (int64)

+
+

Body

+
+

user
+required

+
+

user

+
+

User

+
+
+
+

Responses

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP CodeDescriptionSchema
+

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

+ +++++ + + + + + + + + + + + + + + +
TypeNameScopes
+

apiKey

+
+

global

+
+
+
+
+

删除用户

+
+
+
DELETE /users/{id}
+
+
+
+

Description

+
+

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

+
+
+
+

Parameters

+ ++++++ + + + + + + + + + + + + + + + + +
TypeNameDescriptionSchema
+

Path

+
+

id
+required

+
+

id

+
+

integer (int64)

+
+
+
+

Responses

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP CodeDescriptionSchema
+

200

+
+

OK

+
+

string

+
+

204

+
+

No Content

+
+

No Content

+
+

401

+
+

Unauthorized

+
+

No Content

+
+

403

+
+

Forbidden

+
+

No Content

+
+
+
+

Produces

+
+
    +
  • +

    */*

    +
  • +
+
+
+
+

Tags

+
+
    +
  • +

    用户管理

    +
  • +
+
+
+
+

Security

+ +++++ + + + + + + + + + + + + + + +
TypeNameScopes
+

apiKey

+
+

global

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/2.x/chapter2-5/src/docs/asciidoc/html/security.html b/2.x/chapter2-5/src/docs/asciidoc/html/security.html new file mode 100644 index 00000000..34676fab --- /dev/null +++ b/2.x/chapter2-5/src/docs/asciidoc/html/security.html @@ -0,0 +1,553 @@ + + + + + + + +Security + + + + + + +
+
+

Security

+
+
+

Authorization

+
+

Type : apiKey
+Name : TOKEN
+In : HEADER

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/2.x/chapter2-5/src/docs/confluence/generated/definitions.txt b/2.x/chapter2-5/src/docs/confluence/generated/definitions.txt new file mode 100644 index 00000000..6792429a --- /dev/null +++ b/2.x/chapter2-5/src/docs/confluence/generated/definitions.txt @@ -0,0 +1,14 @@ + +h2. Definitions {anchor:definitions} + +h3. User {anchor:user} +用户实体 + + +||Name||Description||Schema|| +|*age*\\ \\ _optional_||用户年龄||integer (int32)| +|*id*\\ \\ _optional_||用户编号||integer (int64)| +|*name*\\ \\ _optional_||用户姓名||string| + + + diff --git a/2.x/chapter2-5/src/docs/confluence/generated/overview.txt b/2.x/chapter2-5/src/docs/confluence/generated/overview.txt new file mode 100644 index 00000000..af12d61b --- /dev/null +++ b/2.x/chapter2-5/src/docs/confluence/generated/overview.txt @@ -0,0 +1,33 @@ +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 + + + diff --git a/2.x/chapter2-5/src/docs/confluence/generated/paths.txt b/2.x/chapter2-5/src/docs/confluence/generated/paths.txt new file mode 100644 index 00000000..5b169e5d --- /dev/null +++ b/2.x/chapter2-5/src/docs/confluence/generated/paths.txt @@ -0,0 +1,212 @@ + +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| + + + diff --git a/2.x/chapter2-5/src/docs/confluence/generated/security.txt b/2.x/chapter2-5/src/docs/confluence/generated/security.txt new file mode 100644 index 00000000..7594f1b5 --- /dev/null +++ b/2.x/chapter2-5/src/docs/confluence/generated/security.txt @@ -0,0 +1,10 @@ + +h2. Security {anchor:securityscheme} + +h3. Authorization {anchor:authorization} +_Type_ : apiKey\\ +_Name_ : TOKEN\\ +_In_ : HEADER + + + diff --git a/2.x/chapter2-5/src/docs/markdown/generated/definitions.md b/2.x/chapter2-5/src/docs/markdown/generated/definitions.md new file mode 100644 index 00000000..4eaff931 --- /dev/null +++ b/2.x/chapter2-5/src/docs/markdown/generated/definitions.md @@ -0,0 +1,17 @@ + + +## Definitions + + +### User +用户实体 + + +|Name|Description|Schema| +|---|---|---| +|**age**
*optional*|用户年龄|integer (int32)| +|**id**
*optional*|用户编号|integer (int64)| +|**name**
*optional*|用户姓名|string| + + + diff --git a/2.x/chapter2-5/src/docs/markdown/generated/overview.md b/2.x/chapter2-5/src/docs/markdown/generated/overview.md new file mode 100644 index 00000000..d360d5a8 --- /dev/null +++ b/2.x/chapter2-5/src/docs/markdown/generated/overview.md @@ -0,0 +1,34 @@ +# 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 + + + diff --git a/2.x/chapter2-5/src/docs/markdown/generated/paths.md b/2.x/chapter2-5/src/docs/markdown/generated/paths.md new file mode 100644 index 00000000..d056676a --- /dev/null +++ b/2.x/chapter2-5/src/docs/markdown/generated/paths.md @@ -0,0 +1,232 @@ + + +## 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| + + + diff --git a/2.x/chapter2-5/src/docs/markdown/generated/security.md b/2.x/chapter2-5/src/docs/markdown/generated/security.md new file mode 100644 index 00000000..09ee31c4 --- /dev/null +++ b/2.x/chapter2-5/src/docs/markdown/generated/security.md @@ -0,0 +1,12 @@ + + +## Security + + +### Authorization +*Type* : apiKey +*Name* : TOKEN +*In* : HEADER + + + diff --git a/2.x/chapter2-5/src/main/java/com/didispace/chapter25/Chapter25Application.java b/2.x/chapter2-5/src/main/java/com/didispace/chapter25/Chapter25Application.java new file mode 100644 index 00000000..b8c92652 --- /dev/null +++ b/2.x/chapter2-5/src/main/java/com/didispace/chapter25/Chapter25Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter2-5/src/main/java/com/didispace/chapter25/User.java b/2.x/chapter2-5/src/main/java/com/didispace/chapter25/User.java new file mode 100644 index 00000000..d929259d --- /dev/null +++ b/2.x/chapter2-5/src/main/java/com/didispace/chapter25/User.java @@ -0,0 +1,18 @@ +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; + +} \ No newline at end of file diff --git a/2.x/chapter2-5/src/main/java/com/didispace/chapter25/UserController.java b/2.x/chapter2-5/src/main/java/com/didispace/chapter25/UserController.java new file mode 100644 index 00000000..ac333420 --- /dev/null +++ b/2.x/chapter2-5/src/main/java/com/didispace/chapter25/UserController.java @@ -0,0 +1,56 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-5/src/main/resources/application.properties b/2.x/chapter2-5/src/main/resources/application.properties new file mode 100644 index 00000000..55ec2942 --- /dev/null +++ b/2.x/chapter2-5/src/main/resources/application.properties @@ -0,0 +1,13 @@ + + +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=/** \ No newline at end of file diff --git a/2.x/chapter2-5/src/test/java/com/didispace/chapter25/DemoApplicationTests.java b/2.x/chapter2-5/src/test/java/com/didispace/chapter25/DemoApplicationTests.java new file mode 100644 index 00000000..d36e438e --- /dev/null +++ b/2.x/chapter2-5/src/test/java/com/didispace/chapter25/DemoApplicationTests.java @@ -0,0 +1,71 @@ +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); + } + +} \ No newline at end of file diff --git a/2.x/chapter2-6/.gitignore b/2.x/chapter2-6/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter2-6/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter2-6/pom.xml b/2.x/chapter2-6/pom.xml new file mode 100644 index 00000000..f4252540 --- /dev/null +++ b/2.x/chapter2-6/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter2-6/src/main/java/com/didispace/chapter26/Chapter26Application.java b/2.x/chapter2-6/src/main/java/com/didispace/chapter26/Chapter26Application.java new file mode 100644 index 00000000..ab89e203 --- /dev/null +++ b/2.x/chapter2-6/src/main/java/com/didispace/chapter26/Chapter26Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter2-6/src/main/java/com/didispace/chapter26/User.java b/2.x/chapter2-6/src/main/java/com/didispace/chapter26/User.java new file mode 100644 index 00000000..60e131cd --- /dev/null +++ b/2.x/chapter2-6/src/main/java/com/didispace/chapter26/User.java @@ -0,0 +1,12 @@ +package com.didispace.chapter26; + +import lombok.Data; + +@Data +public class User { + + private Long id; + private String name; + private Integer age; + +} \ No newline at end of file diff --git a/2.x/chapter2-6/src/main/java/com/didispace/chapter26/UserController.java b/2.x/chapter2-6/src/main/java/com/didispace/chapter26/UserController.java new file mode 100644 index 00000000..a84cf8d4 --- /dev/null +++ b/2.x/chapter2-6/src/main/java/com/didispace/chapter26/UserController.java @@ -0,0 +1,46 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-6/src/main/resources/application.properties b/2.x/chapter2-6/src/main/resources/application.properties new file mode 100644 index 00000000..eae6a38f --- /dev/null +++ b/2.x/chapter2-6/src/main/resources/application.properties @@ -0,0 +1,3 @@ +# 打印RequestMapping中的所有接口信息 +logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=trace + diff --git a/2.x/chapter2-7/.gitignore b/2.x/chapter2-7/.gitignore new file mode 100644 index 00000000..2af7cefb --- /dev/null +++ b/2.x/chapter2-7/.gitignore @@ -0,0 +1,24 @@ +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/ \ No newline at end of file diff --git a/2.x/chapter2-7/pom.xml b/2.x/chapter2-7/pom.xml new file mode 100644 index 00000000..285eeeea --- /dev/null +++ b/2.x/chapter2-7/pom.xml @@ -0,0 +1,68 @@ + + + 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 + + + + diff --git a/2.x/chapter2-7/src/main/java/com/didispace/chapter27/Chapter27Application.java b/2.x/chapter2-7/src/main/java/com/didispace/chapter27/Chapter27Application.java new file mode 100644 index 00000000..7a6a667b --- /dev/null +++ b/2.x/chapter2-7/src/main/java/com/didispace/chapter27/Chapter27Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter2-7/src/main/java/com/didispace/chapter27/User.java b/2.x/chapter2-7/src/main/java/com/didispace/chapter27/User.java new file mode 100644 index 00000000..25c99ae8 --- /dev/null +++ b/2.x/chapter2-7/src/main/java/com/didispace/chapter27/User.java @@ -0,0 +1,29 @@ +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; + +} \ No newline at end of file diff --git a/2.x/chapter2-7/src/main/java/com/didispace/chapter27/UserController.java b/2.x/chapter2-7/src/main/java/com/didispace/chapter27/UserController.java new file mode 100644 index 00000000..fcfb546d --- /dev/null +++ b/2.x/chapter2-7/src/main/java/com/didispace/chapter27/UserController.java @@ -0,0 +1,45 @@ +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; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-7/src/main/resources/application.properties b/2.x/chapter2-7/src/main/resources/application.properties new file mode 100644 index 00000000..d910c856 --- /dev/null +++ b/2.x/chapter2-7/src/main/resources/application.properties @@ -0,0 +1,2 @@ +logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=trace + diff --git a/2.x/chapter2-8/pom.xml b/2.x/chapter2-8/pom.xml new file mode 100644 index 00000000..86a98950 --- /dev/null +++ b/2.x/chapter2-8/pom.xml @@ -0,0 +1,57 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/2.x/chapter2-8/src/main/java/com/didispace/chapter28/Chapter28Application.java b/2.x/chapter2-8/src/main/java/com/didispace/chapter28/Chapter28Application.java new file mode 100755 index 00000000..6577db14 --- /dev/null +++ b/2.x/chapter2-8/src/main/java/com/didispace/chapter28/Chapter28Application.java @@ -0,0 +1,18 @@ +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); + } + +} diff --git a/2.x/chapter2-8/src/main/java/com/didispace/chapter28/User.java b/2.x/chapter2-8/src/main/java/com/didispace/chapter28/User.java new file mode 100755 index 00000000..5c035bd4 --- /dev/null +++ b/2.x/chapter2-8/src/main/java/com/didispace/chapter28/User.java @@ -0,0 +1,26 @@ +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; + +} diff --git a/2.x/chapter2-8/src/main/java/com/didispace/chapter28/UserController.java b/2.x/chapter2-8/src/main/java/com/didispace/chapter28/UserController.java new file mode 100755 index 00000000..055b4042 --- /dev/null +++ b/2.x/chapter2-8/src/main/java/com/didispace/chapter28/UserController.java @@ -0,0 +1,27 @@ +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; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-8/src/main/resources/application.properties b/2.x/chapter2-8/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/2.x/chapter2-9/pom.xml b/2.x/chapter2-9/pom.xml new file mode 100644 index 00000000..9f670750 --- /dev/null +++ b/2.x/chapter2-9/pom.xml @@ -0,0 +1,75 @@ + + + 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 + + + + \ No newline at end of file diff --git a/2.x/chapter2-9/src/main/java/com/didispace/chapter29/Chapter29Application.java b/2.x/chapter2-9/src/main/java/com/didispace/chapter29/Chapter29Application.java new file mode 100755 index 00000000..c72319b2 --- /dev/null +++ b/2.x/chapter2-9/src/main/java/com/didispace/chapter29/Chapter29Application.java @@ -0,0 +1,18 @@ +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); + } + +} diff --git a/2.x/chapter2-9/src/main/java/com/didispace/chapter29/User.java b/2.x/chapter2-9/src/main/java/com/didispace/chapter29/User.java new file mode 100755 index 00000000..40b2725f --- /dev/null +++ b/2.x/chapter2-9/src/main/java/com/didispace/chapter29/User.java @@ -0,0 +1,26 @@ +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; + +} diff --git a/2.x/chapter2-9/src/main/java/com/didispace/chapter29/UserController.java b/2.x/chapter2-9/src/main/java/com/didispace/chapter29/UserController.java new file mode 100755 index 00000000..d7711fa5 --- /dev/null +++ b/2.x/chapter2-9/src/main/java/com/didispace/chapter29/UserController.java @@ -0,0 +1,27 @@ +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; + } + +} \ No newline at end of file diff --git a/2.x/chapter2-9/src/main/resources/application.properties b/2.x/chapter2-9/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/2.x/chapter3-1/.gitignore b/2.x/chapter3-1/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-1/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-1/pom.xml b/2.x/chapter3-1/pom.xml new file mode 100644 index 00000000..e70062b4 --- /dev/null +++ b/2.x/chapter3-1/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-1/src/main/java/com/didispace/chapter31/Chapter31Application.java b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/Chapter31Application.java new file mode 100644 index 00000000..c83da9dd --- /dev/null +++ b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/Chapter31Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-1/src/main/java/com/didispace/chapter31/User.java b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/User.java new file mode 100644 index 00000000..5c54cf36 --- /dev/null +++ b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/User.java @@ -0,0 +1,13 @@ +package com.didispace.chapter31; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class User { + + private String name; + private Integer age; + +} \ No newline at end of file diff --git a/2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserService.java b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserService.java new file mode 100644 index 00000000..2ce0b727 --- /dev/null +++ b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserService.java @@ -0,0 +1,40 @@ +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(); + +} \ No newline at end of file diff --git a/2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserServiceImpl.java b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserServiceImpl.java new file mode 100644 index 00000000..3cb55fb2 --- /dev/null +++ b/2.x/chapter3-1/src/main/java/com/didispace/chapter31/UserServiceImpl.java @@ -0,0 +1,52 @@ +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"); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-1/src/main/resources/application.properties b/2.x/chapter3-1/src/main/resources/application.properties new file mode 100644 index 00000000..66ff8fe4 --- /dev/null +++ b/2.x/chapter3-1/src/main/resources/application.properties @@ -0,0 +1,4 @@ +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 \ No newline at end of file diff --git a/2.x/chapter3-1/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java b/2.x/chapter3-1/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java new file mode 100644 index 00000000..2905f545 --- /dev/null +++ b/2.x/chapter3-1/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java @@ -0,0 +1,63 @@ +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()); + + } + +} diff --git a/2.x/chapter3-10/.gitignore b/2.x/chapter3-10/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-10/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-10/pom.xml b/2.x/chapter3-10/pom.xml new file mode 100644 index 00000000..72162203 --- /dev/null +++ b/2.x/chapter3-10/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-10/src/main/java/com/didispace/chapter310/Chapter310Application.java b/2.x/chapter3-10/src/main/java/com/didispace/chapter310/Chapter310Application.java new file mode 100644 index 00000000..72a7dd3e --- /dev/null +++ b/2.x/chapter3-10/src/main/java/com/didispace/chapter310/Chapter310Application.java @@ -0,0 +1,25 @@ +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"; + } + + } + +} diff --git a/2.x/chapter3-10/src/main/java/com/didispace/chapter310/User.java b/2.x/chapter3-10/src/main/java/com/didispace/chapter310/User.java new file mode 100644 index 00000000..a2347ea8 --- /dev/null +++ b/2.x/chapter3-10/src/main/java/com/didispace/chapter310/User.java @@ -0,0 +1,27 @@ +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; + } + +} \ No newline at end of file diff --git a/2.x/chapter3-10/src/main/java/com/didispace/chapter310/UserRepository.java b/2.x/chapter3-10/src/main/java/com/didispace/chapter310/UserRepository.java new file mode 100644 index 00000000..366e1d21 --- /dev/null +++ b/2.x/chapter3-10/src/main/java/com/didispace/chapter310/UserRepository.java @@ -0,0 +1,22 @@ +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); + +} diff --git a/2.x/chapter3-10/src/main/resources/application.properties b/2.x/chapter3-10/src/main/resources/application.properties new file mode 100644 index 00000000..7238387a --- /dev/null +++ b/2.x/chapter3-10/src/main/resources/application.properties @@ -0,0 +1,7 @@ +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 diff --git a/2.x/chapter3-10/src/test/java/com/didispace/chapter310/Chapter310ApplicationTests.java b/2.x/chapter3-10/src/test/java/com/didispace/chapter310/Chapter310ApplicationTests.java new file mode 100644 index 00000000..02fee65b --- /dev/null +++ b/2.x/chapter3-10/src/test/java/com/didispace/chapter310/Chapter310ApplicationTests.java @@ -0,0 +1,56 @@ +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()); + + } + +} diff --git a/2.x/chapter3-11/.gitignore b/2.x/chapter3-11/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-11/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-11/pom.xml b/2.x/chapter3-11/pom.xml new file mode 100644 index 00000000..c9692e8d --- /dev/null +++ b/2.x/chapter3-11/pom.xml @@ -0,0 +1,60 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-11/src/main/java/com/didispace/chapter311/Chapter311Application.java b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/Chapter311Application.java new file mode 100644 index 00000000..9273268c --- /dev/null +++ b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/Chapter311Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-11/src/main/java/com/didispace/chapter311/User.java b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/User.java new file mode 100644 index 00000000..1ca17f9c --- /dev/null +++ b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/User.java @@ -0,0 +1,14 @@ +package com.didispace.chapter311; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class User { + + private Long id; + private String name; + private Integer age; + +} \ No newline at end of file diff --git a/2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserService.java b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserService.java new file mode 100644 index 00000000..d5591de0 --- /dev/null +++ b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserService.java @@ -0,0 +1,40 @@ +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(); + +} \ No newline at end of file diff --git a/2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserServiceImpl.java b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserServiceImpl.java new file mode 100644 index 00000000..54aa40fe --- /dev/null +++ b/2.x/chapter3-11/src/main/java/com/didispace/chapter311/UserServiceImpl.java @@ -0,0 +1,49 @@ +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"); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-11/src/main/resources/application.properties b/2.x/chapter3-11/src/main/resources/application.properties new file mode 100644 index 00000000..b36e87bd --- /dev/null +++ b/2.x/chapter3-11/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/2.x/chapter3-11/src/main/resources/db/migration/V1_1__alter_table_user.sql b/2.x/chapter3-11/src/main/resources/db/migration/V1_1__alter_table_user.sql new file mode 100644 index 00000000..667486c5 --- /dev/null +++ b/2.x/chapter3-11/src/main/resources/db/migration/V1_1__alter_table_user.sql @@ -0,0 +1 @@ +ALTER TABLE `user` ADD COLUMN `address` VARCHAR(20) DEFAULT NULL; diff --git a/2.x/chapter3-11/src/main/resources/db/migration/V1__Base_version.sql b/2.x/chapter3-11/src/main/resources/db/migration/V1__Base_version.sql new file mode 100644 index 00000000..428f2187 --- /dev/null +++ b/2.x/chapter3-11/src/main/resources/db/migration/V1__Base_version.sql @@ -0,0 +1,7 @@ +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; diff --git a/2.x/chapter3-11/src/test/java/com/didispace/chapter311/Chapter311ApplicationTests.java b/2.x/chapter3-11/src/test/java/com/didispace/chapter311/Chapter311ApplicationTests.java new file mode 100644 index 00000000..4b902ab9 --- /dev/null +++ b/2.x/chapter3-11/src/test/java/com/didispace/chapter311/Chapter311ApplicationTests.java @@ -0,0 +1,45 @@ +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()); + + } + +} diff --git a/2.x/chapter3-12/.gitignore b/2.x/chapter3-12/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-12/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-12/pom.xml b/2.x/chapter3-12/pom.xml new file mode 100644 index 00000000..a61772d3 --- /dev/null +++ b/2.x/chapter3-12/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-12/src/main/java/com/didispace/chapter312/Chapter312Application.java b/2.x/chapter3-12/src/main/java/com/didispace/chapter312/Chapter312Application.java new file mode 100644 index 00000000..325ef162 --- /dev/null +++ b/2.x/chapter3-12/src/main/java/com/didispace/chapter312/Chapter312Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-12/src/main/java/com/didispace/chapter312/DataSourceConfiguration.java b/2.x/chapter3-12/src/main/java/com/didispace/chapter312/DataSourceConfiguration.java new file mode 100644 index 00000000..8b71d643 --- /dev/null +++ b/2.x/chapter3-12/src/main/java/com/didispace/chapter312/DataSourceConfiguration.java @@ -0,0 +1,40 @@ +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); + } + +} diff --git a/2.x/chapter3-12/src/main/java/com/didispace/chapter312/TestService.java b/2.x/chapter3-12/src/main/java/com/didispace/chapter312/TestService.java new file mode 100644 index 00000000..119241dc --- /dev/null +++ b/2.x/chapter3-12/src/main/java/com/didispace/chapter312/TestService.java @@ -0,0 +1,34 @@ +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(); + } + +} diff --git a/2.x/chapter3-12/src/main/resources/application.properties b/2.x/chapter3-12/src/main/resources/application.properties new file mode 100644 index 00000000..312835d1 --- /dev/null +++ b/2.x/chapter3-12/src/main/resources/application.properties @@ -0,0 +1,31 @@ +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 \ No newline at end of file diff --git a/2.x/chapter3-12/src/test/java/com/didispace/chapter312/Chapter312ApplicationTests.java b/2.x/chapter3-12/src/test/java/com/didispace/chapter312/Chapter312ApplicationTests.java new file mode 100644 index 00000000..649b8b17 --- /dev/null +++ b/2.x/chapter3-12/src/test/java/com/didispace/chapter312/Chapter312ApplicationTests.java @@ -0,0 +1,45 @@ +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")); + } + } + +} diff --git a/2.x/chapter3-13/.gitignore b/2.x/chapter3-13/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-13/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-13/pom.xml b/2.x/chapter3-13/pom.xml new file mode 100644 index 00000000..de7746d3 --- /dev/null +++ b/2.x/chapter3-13/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-13/src/main/java/com/didispace/chapter313/Chapter313Application.java b/2.x/chapter3-13/src/main/java/com/didispace/chapter313/Chapter313Application.java new file mode 100644 index 00000000..88768410 --- /dev/null +++ b/2.x/chapter3-13/src/main/java/com/didispace/chapter313/Chapter313Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-13/src/main/resources/application.properties b/2.x/chapter3-13/src/main/resources/application.properties new file mode 100644 index 00000000..225ddd22 --- /dev/null +++ b/2.x/chapter3-13/src/main/resources/application.properties @@ -0,0 +1,15 @@ +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 + diff --git a/2.x/chapter3-13/src/main/resources/schema-all.sql b/2.x/chapter3-13/src/main/resources/schema-all.sql new file mode 100644 index 00000000..cdbe26c1 --- /dev/null +++ b/2.x/chapter3-13/src/main/resources/schema-all.sql @@ -0,0 +1,18 @@ +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 '用户表'; + diff --git a/2.x/chapter3-13/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java b/2.x/chapter3-13/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java new file mode 100644 index 00000000..e65f6029 --- /dev/null +++ b/2.x/chapter3-13/src/test/java/com/didispace/chapter31/Chapter31ApplicationTests.java @@ -0,0 +1,17 @@ +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 { + + + } + +} diff --git a/2.x/chapter3-2/.gitignore b/2.x/chapter3-2/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-2/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-2/pom.xml b/2.x/chapter3-2/pom.xml new file mode 100644 index 00000000..d3a5f35d --- /dev/null +++ b/2.x/chapter3-2/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-2/src/main/java/com/didispace/chapter32/Chapter32Application.java b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/Chapter32Application.java new file mode 100644 index 00000000..d782cff1 --- /dev/null +++ b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/Chapter32Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-2/src/main/java/com/didispace/chapter32/User.java b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/User.java new file mode 100644 index 00000000..7553c2e2 --- /dev/null +++ b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/User.java @@ -0,0 +1,13 @@ +package com.didispace.chapter32; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class User { + + private String name; + private Integer age; + +} \ No newline at end of file diff --git a/2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserService.java b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserService.java new file mode 100644 index 00000000..c4e3cd02 --- /dev/null +++ b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserService.java @@ -0,0 +1,40 @@ +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(); + +} \ No newline at end of file diff --git a/2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserServiceImpl.java b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserServiceImpl.java new file mode 100644 index 00000000..9fb1bd08 --- /dev/null +++ b/2.x/chapter3-2/src/main/java/com/didispace/chapter32/UserServiceImpl.java @@ -0,0 +1,52 @@ +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"); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-2/src/main/resources/application.properties b/2.x/chapter3-2/src/main/resources/application.properties new file mode 100644 index 00000000..b0d32069 --- /dev/null +++ b/2.x/chapter3-2/src/main/resources/application.properties @@ -0,0 +1,17 @@ +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 diff --git a/2.x/chapter3-2/src/test/java/com/didispace/chapter32/Chapter32ApplicationTests.java b/2.x/chapter3-2/src/test/java/com/didispace/chapter32/Chapter32ApplicationTests.java new file mode 100644 index 00000000..e23dd01c --- /dev/null +++ b/2.x/chapter3-2/src/test/java/com/didispace/chapter32/Chapter32ApplicationTests.java @@ -0,0 +1,69 @@ +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()); + + } + +} diff --git a/2.x/chapter3-3/.gitignore b/2.x/chapter3-3/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-3/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-3/pom.xml b/2.x/chapter3-3/pom.xml new file mode 100644 index 00000000..63a0dbe3 --- /dev/null +++ b/2.x/chapter3-3/pom.xml @@ -0,0 +1,71 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-3/src/main/java/com/didispace/chapter33/Chapter33Application.java b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/Chapter33Application.java new file mode 100644 index 00000000..4653f680 --- /dev/null +++ b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/Chapter33Application.java @@ -0,0 +1,25 @@ +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"; + } + + } + +} diff --git a/2.x/chapter3-3/src/main/java/com/didispace/chapter33/User.java b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/User.java new file mode 100644 index 00000000..ac0b9460 --- /dev/null +++ b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/User.java @@ -0,0 +1,13 @@ +package com.didispace.chapter33; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class User { + + private String name; + private Integer age; + +} \ No newline at end of file diff --git a/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserController.java b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserController.java new file mode 100644 index 00000000..f88d0dc0 --- /dev/null +++ b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserController.java @@ -0,0 +1,47 @@ +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(); + } + +} diff --git a/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserService.java b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserService.java new file mode 100644 index 00000000..7eddffb5 --- /dev/null +++ b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserService.java @@ -0,0 +1,40 @@ +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(); + +} \ No newline at end of file diff --git a/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserServiceImpl.java b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserServiceImpl.java new file mode 100644 index 00000000..43f0f79a --- /dev/null +++ b/2.x/chapter3-3/src/main/java/com/didispace/chapter33/UserServiceImpl.java @@ -0,0 +1,52 @@ +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"); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-3/src/main/resources/application.properties b/2.x/chapter3-3/src/main/resources/application.properties new file mode 100644 index 00000000..26f3a97b --- /dev/null +++ b/2.x/chapter3-3/src/main/resources/application.properties @@ -0,0 +1,29 @@ + +# 基础配置 +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 diff --git a/2.x/chapter3-3/src/test/java/com/didispace/chapter33/Chapter33ApplicationTests.java b/2.x/chapter3-3/src/test/java/com/didispace/chapter33/Chapter33ApplicationTests.java new file mode 100644 index 00000000..f86be74a --- /dev/null +++ b/2.x/chapter3-3/src/test/java/com/didispace/chapter33/Chapter33ApplicationTests.java @@ -0,0 +1,69 @@ +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()); + + } + +} diff --git a/2.x/chapter3-4/.gitignore b/2.x/chapter3-4/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-4/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-4/pom.xml b/2.x/chapter3-4/pom.xml new file mode 100644 index 00000000..d529c02b --- /dev/null +++ b/2.x/chapter3-4/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-4/src/main/java/com/didispace/chapter34/Chapter34Application.java b/2.x/chapter3-4/src/main/java/com/didispace/chapter34/Chapter34Application.java new file mode 100644 index 00000000..4b9e8193 --- /dev/null +++ b/2.x/chapter3-4/src/main/java/com/didispace/chapter34/Chapter34Application.java @@ -0,0 +1,25 @@ +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"; + } + + } + +} diff --git a/2.x/chapter3-4/src/main/java/com/didispace/chapter34/User.java b/2.x/chapter3-4/src/main/java/com/didispace/chapter34/User.java new file mode 100644 index 00000000..701ed4d4 --- /dev/null +++ b/2.x/chapter3-4/src/main/java/com/didispace/chapter34/User.java @@ -0,0 +1,26 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter3-4/src/main/java/com/didispace/chapter34/UserRepository.java b/2.x/chapter3-4/src/main/java/com/didispace/chapter34/UserRepository.java new file mode 100644 index 00000000..17533dd3 --- /dev/null +++ b/2.x/chapter3-4/src/main/java/com/didispace/chapter34/UserRepository.java @@ -0,0 +1,22 @@ +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); + +} diff --git a/2.x/chapter3-4/src/main/resources/application.properties b/2.x/chapter3-4/src/main/resources/application.properties new file mode 100644 index 00000000..44c64de2 --- /dev/null +++ b/2.x/chapter3-4/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/2.x/chapter3-4/src/test/java/com/didispace/chapter34/Chapter34ApplicationTests.java b/2.x/chapter3-4/src/test/java/com/didispace/chapter34/Chapter34ApplicationTests.java new file mode 100644 index 00000000..e104e22c --- /dev/null +++ b/2.x/chapter3-4/src/test/java/com/didispace/chapter34/Chapter34ApplicationTests.java @@ -0,0 +1,57 @@ +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()); + + } + +} diff --git a/2.x/chapter3-5/.gitignore b/2.x/chapter3-5/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-5/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-5/pom.xml b/2.x/chapter3-5/pom.xml new file mode 100644 index 00000000..43bfeb2a --- /dev/null +++ b/2.x/chapter3-5/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-5/src/main/java/com/didispace/chapter35/Chapter35Application.java b/2.x/chapter3-5/src/main/java/com/didispace/chapter35/Chapter35Application.java new file mode 100644 index 00000000..48e71f85 --- /dev/null +++ b/2.x/chapter3-5/src/main/java/com/didispace/chapter35/Chapter35Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-5/src/main/java/com/didispace/chapter35/User.java b/2.x/chapter3-5/src/main/java/com/didispace/chapter35/User.java new file mode 100644 index 00000000..d815f4c1 --- /dev/null +++ b/2.x/chapter3-5/src/main/java/com/didispace/chapter35/User.java @@ -0,0 +1,20 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter3-5/src/main/java/com/didispace/chapter35/UserMapper.java b/2.x/chapter3-5/src/main/java/com/didispace/chapter35/UserMapper.java new file mode 100644 index 00000000..17f6aa18 --- /dev/null +++ b/2.x/chapter3-5/src/main/java/com/didispace/chapter35/UserMapper.java @@ -0,0 +1,23 @@ +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); + +} diff --git a/2.x/chapter3-5/src/main/resources/application.properties b/2.x/chapter3-5/src/main/resources/application.properties new file mode 100644 index 00000000..779d89b9 --- /dev/null +++ b/2.x/chapter3-5/src/main/resources/application.properties @@ -0,0 +1,4 @@ +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 diff --git a/2.x/chapter3-5/src/test/java/com/didispace/chapter35/Chapter35ApplicationTests.java b/2.x/chapter3-5/src/test/java/com/didispace/chapter35/Chapter35ApplicationTests.java new file mode 100644 index 00000000..b6de7a08 --- /dev/null +++ b/2.x/chapter3-5/src/test/java/com/didispace/chapter35/Chapter35ApplicationTests.java @@ -0,0 +1,33 @@ +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()); + } + +} diff --git a/2.x/chapter3-6/.gitignore b/2.x/chapter3-6/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-6/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-6/pom.xml b/2.x/chapter3-6/pom.xml new file mode 100644 index 00000000..97869305 --- /dev/null +++ b/2.x/chapter3-6/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-6/src/main/java/com/didispace/chapter36/Chapter36Application.java b/2.x/chapter3-6/src/main/java/com/didispace/chapter36/Chapter36Application.java new file mode 100644 index 00000000..2ce02b15 --- /dev/null +++ b/2.x/chapter3-6/src/main/java/com/didispace/chapter36/Chapter36Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter3-6/src/main/java/com/didispace/chapter36/entity/User.java b/2.x/chapter3-6/src/main/java/com/didispace/chapter36/entity/User.java new file mode 100644 index 00000000..6196ed6d --- /dev/null +++ b/2.x/chapter3-6/src/main/java/com/didispace/chapter36/entity/User.java @@ -0,0 +1,20 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter3-6/src/main/java/com/didispace/chapter36/mapper/UserMapper.java b/2.x/chapter3-6/src/main/java/com/didispace/chapter36/mapper/UserMapper.java new file mode 100644 index 00000000..cd361f46 --- /dev/null +++ b/2.x/chapter3-6/src/main/java/com/didispace/chapter36/mapper/UserMapper.java @@ -0,0 +1,18 @@ +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); + +} diff --git a/2.x/chapter3-6/src/main/resources/application.properties b/2.x/chapter3-6/src/main/resources/application.properties new file mode 100644 index 00000000..ec5cde49 --- /dev/null +++ b/2.x/chapter3-6/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 diff --git a/2.x/chapter3-6/src/main/resources/mapper/UserMapper.xml b/2.x/chapter3-6/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 00000000..520d290e --- /dev/null +++ b/2.x/chapter3-6/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,13 @@ + + + + + + + INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age}) + + \ No newline at end of file diff --git a/2.x/chapter3-6/src/test/java/com/didispace/chapter36/Chapter36ApplicationTests.java b/2.x/chapter3-6/src/test/java/com/didispace/chapter36/Chapter36ApplicationTests.java new file mode 100644 index 00000000..aab8acb1 --- /dev/null +++ b/2.x/chapter3-6/src/test/java/com/didispace/chapter36/Chapter36ApplicationTests.java @@ -0,0 +1,32 @@ +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()); + } + +} diff --git a/2.x/chapter3-7/.gitignore b/2.x/chapter3-7/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-7/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-7/pom.xml b/2.x/chapter3-7/pom.xml new file mode 100644 index 00000000..589d40ec --- /dev/null +++ b/2.x/chapter3-7/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-7/src/main/java/com/didispace/chapter37/Chapter37Application.java b/2.x/chapter3-7/src/main/java/com/didispace/chapter37/Chapter37Application.java new file mode 100644 index 00000000..92be7068 --- /dev/null +++ b/2.x/chapter3-7/src/main/java/com/didispace/chapter37/Chapter37Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-7/src/main/java/com/didispace/chapter37/DataSourceConfiguration.java b/2.x/chapter3-7/src/main/java/com/didispace/chapter37/DataSourceConfiguration.java new file mode 100644 index 00000000..f821153b --- /dev/null +++ b/2.x/chapter3-7/src/main/java/com/didispace/chapter37/DataSourceConfiguration.java @@ -0,0 +1,39 @@ +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); + } + +} diff --git a/2.x/chapter3-7/src/main/resources/application.properties b/2.x/chapter3-7/src/main/resources/application.properties new file mode 100644 index 00000000..25937c84 --- /dev/null +++ b/2.x/chapter3-7/src/main/resources/application.properties @@ -0,0 +1,11 @@ +# 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 \ No newline at end of file diff --git a/2.x/chapter3-7/src/test/java/com/didispace/chapter37/Chapter37ApplicationTests.java b/2.x/chapter3-7/src/test/java/com/didispace/chapter37/Chapter37ApplicationTests.java new file mode 100644 index 00000000..5aa8a72f --- /dev/null +++ b/2.x/chapter3-7/src/test/java/com/didispace/chapter37/Chapter37ApplicationTests.java @@ -0,0 +1,46 @@ +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)); + } + +} diff --git a/2.x/chapter3-8/.gitignore b/2.x/chapter3-8/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-8/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-8/pom.xml b/2.x/chapter3-8/pom.xml new file mode 100644 index 00000000..fcb9d03a --- /dev/null +++ b/2.x/chapter3-8/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/Chapter38Application.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/Chapter38Application.java new file mode 100644 index 00000000..d2e5f499 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/Chapter38Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/DataSourceConfiguration.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/DataSourceConfiguration.java new file mode 100644 index 00000000..6470beb6 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/DataSourceConfiguration.java @@ -0,0 +1,29 @@ +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(); + } + +} diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/PrimaryConfig.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/PrimaryConfig.java new file mode 100644 index 00000000..3bcfadc0 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/PrimaryConfig.java @@ -0,0 +1,70 @@ +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()); + } + + +} \ No newline at end of file diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/SecondaryConfig.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/SecondaryConfig.java new file mode 100644 index 00000000..7b8df6a3 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/SecondaryConfig.java @@ -0,0 +1,62 @@ +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()); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/User.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/User.java new file mode 100644 index 00000000..83aaf3c9 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/User.java @@ -0,0 +1,27 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/UserRepository.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/UserRepository.java new file mode 100644 index 00000000..e91080e1 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/p/UserRepository.java @@ -0,0 +1,15 @@ +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 { + +} diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/Message.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/Message.java new file mode 100644 index 00000000..956178b8 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/Message.java @@ -0,0 +1,29 @@ +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; + } + +} \ No newline at end of file diff --git a/2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/MessageRepository.java b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/MessageRepository.java new file mode 100644 index 00000000..13360488 --- /dev/null +++ b/2.x/chapter3-8/src/main/java/com/didispace/chapter38/s/MessageRepository.java @@ -0,0 +1,14 @@ +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 { + + +} diff --git a/2.x/chapter3-8/src/main/resources/application.properties b/2.x/chapter3-8/src/main/resources/application.properties new file mode 100644 index 00000000..0d82f6cd --- /dev/null +++ b/2.x/chapter3-8/src/main/resources/application.properties @@ -0,0 +1,16 @@ +# 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 diff --git a/2.x/chapter3-8/src/test/java/com/didispace/chapter38/Chapter38ApplicationTests.java b/2.x/chapter3-8/src/test/java/com/didispace/chapter38/Chapter38ApplicationTests.java new file mode 100644 index 00000000..9c9ef3e7 --- /dev/null +++ b/2.x/chapter3-8/src/test/java/com/didispace/chapter38/Chapter38ApplicationTests.java @@ -0,0 +1,42 @@ +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()); + } + +} diff --git a/2.x/chapter3-9/.gitignore b/2.x/chapter3-9/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter3-9/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter3-9/pom.xml b/2.x/chapter3-9/pom.xml new file mode 100644 index 00000000..c8f731ef --- /dev/null +++ b/2.x/chapter3-9/pom.xml @@ -0,0 +1,56 @@ + + + 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 + + + + + diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/Chapter39Application.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/Chapter39Application.java new file mode 100644 index 00000000..eb46b057 --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/Chapter39Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/DataSourceConfiguration.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/DataSourceConfiguration.java new file mode 100644 index 00000000..6eaae095 --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/DataSourceConfiguration.java @@ -0,0 +1,27 @@ +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(); + } + +} diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/PrimaryConfig.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/PrimaryConfig.java new file mode 100644 index 00000000..f6d1bbe5 --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/PrimaryConfig.java @@ -0,0 +1,38 @@ +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()); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/SecondaryConfig.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/SecondaryConfig.java new file mode 100644 index 00000000..bdb17fba --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/SecondaryConfig.java @@ -0,0 +1,38 @@ +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()); + } + +} \ No newline at end of file diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/entity/UserPrimary.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/entity/UserPrimary.java new file mode 100644 index 00000000..f4c2a299 --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/entity/UserPrimary.java @@ -0,0 +1,20 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/mapper/UserMapperPrimary.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/mapper/UserMapperPrimary.java new file mode 100644 index 00000000..869ab546 --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/p/mapper/UserMapperPrimary.java @@ -0,0 +1,26 @@ +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(); + +} diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/entity/UserSecondary.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/entity/UserSecondary.java new file mode 100644 index 00000000..fdd64dff --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/entity/UserSecondary.java @@ -0,0 +1,20 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/mapper/UserMapperSecondary.java b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/mapper/UserMapperSecondary.java new file mode 100644 index 00000000..bb4b004c --- /dev/null +++ b/2.x/chapter3-9/src/main/java/com/didispace/chapter39/s/mapper/UserMapperSecondary.java @@ -0,0 +1,25 @@ +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(); +} diff --git a/2.x/chapter3-9/src/main/resources/application.properties b/2.x/chapter3-9/src/main/resources/application.properties new file mode 100644 index 00000000..87777023 --- /dev/null +++ b/2.x/chapter3-9/src/main/resources/application.properties @@ -0,0 +1,13 @@ +# 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 diff --git a/2.x/chapter3-9/src/main/resources/mapper.primary/UserMapper.xml b/2.x/chapter3-9/src/main/resources/mapper.primary/UserMapper.xml new file mode 100644 index 00000000..6eae360b --- /dev/null +++ b/2.x/chapter3-9/src/main/resources/mapper.primary/UserMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age}) + + + \ No newline at end of file diff --git a/2.x/chapter3-9/src/main/resources/mapper.secondary/UserMapper.xml b/2.x/chapter3-9/src/main/resources/mapper.secondary/UserMapper.xml new file mode 100644 index 00000000..361cd16e --- /dev/null +++ b/2.x/chapter3-9/src/main/resources/mapper.secondary/UserMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age}) + + + \ No newline at end of file diff --git a/2.x/chapter3-9/src/test/java/com/didispace/chapter39/Chapter39ApplicationTests.java b/2.x/chapter3-9/src/test/java/com/didispace/chapter39/Chapter39ApplicationTests.java new file mode 100644 index 00000000..a1bd3a81 --- /dev/null +++ b/2.x/chapter3-9/src/test/java/com/didispace/chapter39/Chapter39ApplicationTests.java @@ -0,0 +1,60 @@ +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()); + } + +} diff --git a/2.x/chapter4-1/.gitignore b/2.x/chapter4-1/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter4-1/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter4-1/pom.xml b/2.x/chapter4-1/pom.xml new file mode 100644 index 00000000..07c54958 --- /dev/null +++ b/2.x/chapter4-1/pom.xml @@ -0,0 +1,55 @@ + + + 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 + + + + + diff --git a/2.x/chapter4-1/src/main/java/com/didispace/chapter41/Chapter41Application.java b/2.x/chapter4-1/src/main/java/com/didispace/chapter41/Chapter41Application.java new file mode 100644 index 00000000..8ec9c806 --- /dev/null +++ b/2.x/chapter4-1/src/main/java/com/didispace/chapter41/Chapter41Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter4-1/src/main/java/com/didispace/chapter41/HelloController.java b/2.x/chapter4-1/src/main/java/com/didispace/chapter41/HelloController.java new file mode 100644 index 00000000..314074d1 --- /dev/null +++ b/2.x/chapter4-1/src/main/java/com/didispace/chapter41/HelloController.java @@ -0,0 +1,19 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter4-1/src/main/resources/application.properties b/2.x/chapter4-1/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/2.x/chapter4-1/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/2.x/chapter4-1/src/main/resources/templates/index.html b/2.x/chapter4-1/src/main/resources/templates/index.html new file mode 100644 index 00000000..32cbfe84 --- /dev/null +++ b/2.x/chapter4-1/src/main/resources/templates/index.html @@ -0,0 +1,10 @@ + + + + + + + +

Hello World

+ + \ No newline at end of file diff --git a/2.x/chapter4-2/.gitignore b/2.x/chapter4-2/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter4-2/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter4-2/pom.xml b/2.x/chapter4-2/pom.xml new file mode 100644 index 00000000..26b9d0e6 --- /dev/null +++ b/2.x/chapter4-2/pom.xml @@ -0,0 +1,55 @@ + + + 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 + + + + + diff --git a/2.x/chapter4-2/src/main/java/com/didispace/chapter42/Chapter42Application.java b/2.x/chapter4-2/src/main/java/com/didispace/chapter42/Chapter42Application.java new file mode 100644 index 00000000..00b646c5 --- /dev/null +++ b/2.x/chapter4-2/src/main/java/com/didispace/chapter42/Chapter42Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter4-2/src/main/java/com/didispace/chapter42/HelloController.java b/2.x/chapter4-2/src/main/java/com/didispace/chapter42/HelloController.java new file mode 100644 index 00000000..0e01264b --- /dev/null +++ b/2.x/chapter4-2/src/main/java/com/didispace/chapter42/HelloController.java @@ -0,0 +1,16 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter4-2/src/main/resources/application.properties b/2.x/chapter4-2/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/2.x/chapter4-2/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/2.x/chapter4-2/src/main/resources/templates/index.html b/2.x/chapter4-2/src/main/resources/templates/index.html new file mode 100644 index 00000000..7c8a648b --- /dev/null +++ b/2.x/chapter4-2/src/main/resources/templates/index.html @@ -0,0 +1,30 @@ + + + + + Spring Boot中使用ECharts + + + +
+ + + + \ No newline at end of file diff --git a/2.x/chapter4-3/.gitignore b/2.x/chapter4-3/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter4-3/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter4-3/pom.xml b/2.x/chapter4-3/pom.xml new file mode 100644 index 00000000..21238608 --- /dev/null +++ b/2.x/chapter4-3/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + diff --git a/2.x/chapter4-3/src/main/java/com/didispace/chapter43/Chapter43Application.java b/2.x/chapter4-3/src/main/java/com/didispace/chapter43/Chapter43Application.java new file mode 100644 index 00000000..f54783ed --- /dev/null +++ b/2.x/chapter4-3/src/main/java/com/didispace/chapter43/Chapter43Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter4-3/src/main/java/com/didispace/chapter43/UploadController.java b/2.x/chapter4-3/src/main/java/com/didispace/chapter43/UploadController.java new file mode 100644 index 00000000..e36f32b2 --- /dev/null +++ b/2.x/chapter4-3/src/main/java/com/didispace/chapter43/UploadController.java @@ -0,0 +1,39 @@ +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(); + } + +} \ No newline at end of file diff --git a/2.x/chapter4-3/src/main/resources/application.properties b/2.x/chapter4-3/src/main/resources/application.properties new file mode 100644 index 00000000..08991f4c --- /dev/null +++ b/2.x/chapter4-3/src/main/resources/application.properties @@ -0,0 +1,5 @@ + +spring.servlet.multipart.max-file-size=2MB +spring.servlet.multipart.max-request-size=2MB + +file.upload.path=/Users/zhaiyongchao/ \ No newline at end of file diff --git a/2.x/chapter4-3/src/main/resources/templates/upload.html b/2.x/chapter4-3/src/main/resources/templates/upload.html new file mode 100644 index 00000000..59b8166a --- /dev/null +++ b/2.x/chapter4-3/src/main/resources/templates/upload.html @@ -0,0 +1,15 @@ + + + + + 文件上传页面 + + +

文件上传页面

+
+ 选择要上传的文件:
+
+ +
+ + \ No newline at end of file diff --git a/2.x/chapter4-3/src/test/java/FileTest.java b/2.x/chapter4-3/src/test/java/FileTest.java new file mode 100644 index 00000000..d19d55e0 --- /dev/null +++ b/2.x/chapter4-3/src/test/java/FileTest.java @@ -0,0 +1,48 @@ +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(); + } + +} diff --git a/2.x/chapter4-4/.gitignore b/2.x/chapter4-4/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter4-4/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter4-4/pom.xml b/2.x/chapter4-4/pom.xml new file mode 100644 index 00000000..49da68de --- /dev/null +++ b/2.x/chapter4-4/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + diff --git a/2.x/chapter4-4/src/main/java/com/didispace/chapter44/Chapter44Application.java b/2.x/chapter4-4/src/main/java/com/didispace/chapter44/Chapter44Application.java new file mode 100644 index 00000000..a0145c56 --- /dev/null +++ b/2.x/chapter4-4/src/main/java/com/didispace/chapter44/Chapter44Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter4-4/src/main/java/com/didispace/chapter44/UploadController.java b/2.x/chapter4-4/src/main/java/com/didispace/chapter44/UploadController.java new file mode 100644 index 00000000..82ce1741 --- /dev/null +++ b/2.x/chapter4-4/src/main/java/com/didispace/chapter44/UploadController.java @@ -0,0 +1,44 @@ +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(); + } + +} \ No newline at end of file diff --git a/2.x/chapter4-4/src/main/resources/application.properties b/2.x/chapter4-4/src/main/resources/application.properties new file mode 100644 index 00000000..0d9500e2 --- /dev/null +++ b/2.x/chapter4-4/src/main/resources/application.properties @@ -0,0 +1,5 @@ + +spring.servlet.multipart.max-file-size=2MB +spring.servlet.multipart.max-request-size=2MB + +file.upload.path=/Users/didi/ \ No newline at end of file diff --git a/2.x/chapter4-4/src/main/resources/templates/upload.html b/2.x/chapter4-4/src/main/resources/templates/upload.html new file mode 100644 index 00000000..b7307dac --- /dev/null +++ b/2.x/chapter4-4/src/main/resources/templates/upload.html @@ -0,0 +1,16 @@ + + + + + 文件上传页面 + + +

文件上传页面

+
+ 文件1:
+ 文件2:
+
+ +
+ + \ No newline at end of file diff --git a/2.x/chapter4-4/src/test/java/FileTest.java b/2.x/chapter4-4/src/test/java/FileTest.java new file mode 100644 index 00000000..04cdeb58 --- /dev/null +++ b/2.x/chapter4-4/src/test/java/FileTest.java @@ -0,0 +1,11 @@ +import org.junit.jupiter.api.Test; + +public class FileTest { + + @Test + public void uploadFile() throws Exception { + + + } + +} diff --git a/2.x/chapter4-5/pom.xml b/2.x/chapter4-5/pom.xml new file mode 100644 index 00000000..7120c77a --- /dev/null +++ b/2.x/chapter4-5/pom.xml @@ -0,0 +1,63 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/2.x/chapter4-5/src/main/java/com/didispace/chapter45/Application.java b/2.x/chapter4-5/src/main/java/com/didispace/chapter45/Application.java new file mode 100644 index 00000000..00d2d076 --- /dev/null +++ b/2.x/chapter4-5/src/main/java/com/didispace/chapter45/Application.java @@ -0,0 +1,22 @@ +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); + + } + +} diff --git a/2.x/chapter4-5/src/main/java/com/didispace/chapter45/HelloController.java b/2.x/chapter4-5/src/main/java/com/didispace/chapter45/HelloController.java new file mode 100644 index 00000000..849a125d --- /dev/null +++ b/2.x/chapter4-5/src/main/java/com/didispace/chapter45/HelloController.java @@ -0,0 +1,33 @@ +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"; + } + +} \ No newline at end of file diff --git a/2.x/chapter4-5/src/main/java/com/didispace/chapter45/WebSecurityConfig.java b/2.x/chapter4-5/src/main/java/com/didispace/chapter45/WebSecurityConfig.java new file mode 100644 index 00000000..30fffef5 --- /dev/null +++ b/2.x/chapter4-5/src/main/java/com/didispace/chapter45/WebSecurityConfig.java @@ -0,0 +1,36 @@ +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"); + } + +} \ No newline at end of file diff --git a/2.x/chapter4-5/src/main/resources/application.properties b/2.x/chapter4-5/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/2.x/chapter4-5/src/main/resources/templates/hello.html b/2.x/chapter4-5/src/main/resources/templates/hello.html new file mode 100644 index 00000000..51477131 --- /dev/null +++ b/2.x/chapter4-5/src/main/resources/templates/hello.html @@ -0,0 +1,13 @@ + + + + Hello World! + + +

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

+
+ +
+ + \ No newline at end of file diff --git a/2.x/chapter4-5/src/main/resources/templates/index.html b/2.x/chapter4-5/src/main/resources/templates/index.html new file mode 100644 index 00000000..ffe28340 --- /dev/null +++ b/2.x/chapter4-5/src/main/resources/templates/index.html @@ -0,0 +1,12 @@ + + + + Spring Security入门 + + +

欢迎使用Spring Security!

+ +

点击 这里 打个招呼吧

+ + \ No newline at end of file diff --git a/2.x/chapter4-5/src/main/resources/templates/login.html b/2.x/chapter4-5/src/main/resources/templates/login.html new file mode 100644 index 00000000..f5cbe8e2 --- /dev/null +++ b/2.x/chapter4-5/src/main/resources/templates/login.html @@ -0,0 +1,21 @@ + + + + Spring Security Example + + +
+ 用户名或密码错 +
+
+ 您已注销成功 +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/2.x/chapter5-1/.gitignore b/2.x/chapter5-1/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter5-1/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter5-1/pom.xml b/2.x/chapter5-1/pom.xml new file mode 100644 index 00000000..19540eff --- /dev/null +++ b/2.x/chapter5-1/pom.xml @@ -0,0 +1,70 @@ + + + 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 + + + + + diff --git a/2.x/chapter5-1/src/main/java/com/didispace/chapter51/Chapter51Application.java b/2.x/chapter5-1/src/main/java/com/didispace/chapter51/Chapter51Application.java new file mode 100644 index 00000000..b855c592 --- /dev/null +++ b/2.x/chapter5-1/src/main/java/com/didispace/chapter51/Chapter51Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter5-1/src/main/java/com/didispace/chapter51/User.java b/2.x/chapter5-1/src/main/java/com/didispace/chapter51/User.java new file mode 100644 index 00000000..55ae4a76 --- /dev/null +++ b/2.x/chapter5-1/src/main/java/com/didispace/chapter51/User.java @@ -0,0 +1,26 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter5-1/src/main/java/com/didispace/chapter51/UserRepository.java b/2.x/chapter5-1/src/main/java/com/didispace/chapter51/UserRepository.java new file mode 100644 index 00000000..2785e7ae --- /dev/null +++ b/2.x/chapter5-1/src/main/java/com/didispace/chapter51/UserRepository.java @@ -0,0 +1,26 @@ +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); + +} diff --git a/2.x/chapter5-1/src/main/resources/application.properties b/2.x/chapter5-1/src/main/resources/application.properties new file mode 100644 index 00000000..ba1e5990 --- /dev/null +++ b/2.x/chapter5-1/src/main/resources/application.properties @@ -0,0 +1,7 @@ +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 \ No newline at end of file diff --git a/2.x/chapter5-1/src/test/java/com/didispace/chapter51/Chapter51ApplicationTests.java b/2.x/chapter5-1/src/test/java/com/didispace/chapter51/Chapter51ApplicationTests.java new file mode 100644 index 00000000..3d4dabbd --- /dev/null +++ b/2.x/chapter5-1/src/test/java/com/didispace/chapter51/Chapter51ApplicationTests.java @@ -0,0 +1,34 @@ +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()); + } + +} diff --git a/2.x/chapter5-2/.gitignore b/2.x/chapter5-2/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter5-2/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter5-2/pom.xml b/2.x/chapter5-2/pom.xml new file mode 100644 index 00000000..affc2e9c --- /dev/null +++ b/2.x/chapter5-2/pom.xml @@ -0,0 +1,75 @@ + + + 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 + + + + + diff --git a/2.x/chapter5-2/src/main/java/com/didispace/chapter52/Chapter52Application.java b/2.x/chapter5-2/src/main/java/com/didispace/chapter52/Chapter52Application.java new file mode 100644 index 00000000..e4842885 --- /dev/null +++ b/2.x/chapter5-2/src/main/java/com/didispace/chapter52/Chapter52Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter5-2/src/main/java/com/didispace/chapter52/User.java b/2.x/chapter5-2/src/main/java/com/didispace/chapter52/User.java new file mode 100644 index 00000000..9fb641f0 --- /dev/null +++ b/2.x/chapter5-2/src/main/java/com/didispace/chapter52/User.java @@ -0,0 +1,26 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter5-2/src/main/java/com/didispace/chapter52/UserRepository.java b/2.x/chapter5-2/src/main/java/com/didispace/chapter52/UserRepository.java new file mode 100644 index 00000000..4dad3d06 --- /dev/null +++ b/2.x/chapter5-2/src/main/java/com/didispace/chapter52/UserRepository.java @@ -0,0 +1,21 @@ +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); + +} diff --git a/2.x/chapter5-2/src/main/resources/application.properties b/2.x/chapter5-2/src/main/resources/application.properties new file mode 100644 index 00000000..ba1e5990 --- /dev/null +++ b/2.x/chapter5-2/src/main/resources/application.properties @@ -0,0 +1,7 @@ +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 \ No newline at end of file diff --git a/2.x/chapter5-2/src/main/resources/ehcache.xml b/2.x/chapter5-2/src/main/resources/ehcache.xml new file mode 100644 index 00000000..c178cc9f --- /dev/null +++ b/2.x/chapter5-2/src/main/resources/ehcache.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/2.x/chapter5-2/src/test/java/com/didispace/chapter52/Chapter52ApplicationTests.java b/2.x/chapter5-2/src/test/java/com/didispace/chapter52/Chapter52ApplicationTests.java new file mode 100644 index 00000000..76c505c9 --- /dev/null +++ b/2.x/chapter5-2/src/test/java/com/didispace/chapter52/Chapter52ApplicationTests.java @@ -0,0 +1,36 @@ +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()); + } + +} diff --git a/2.x/chapter5-3/.gitignore b/2.x/chapter5-3/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter5-3/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter5-3/pom.xml b/2.x/chapter5-3/pom.xml new file mode 100644 index 00000000..5c729543 --- /dev/null +++ b/2.x/chapter5-3/pom.xml @@ -0,0 +1,75 @@ + + + 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 + + + + + diff --git a/2.x/chapter5-3/src/main/java/com/didispace/chapter53/Chapter53Application.java b/2.x/chapter5-3/src/main/java/com/didispace/chapter53/Chapter53Application.java new file mode 100644 index 00000000..3abe9f33 --- /dev/null +++ b/2.x/chapter5-3/src/main/java/com/didispace/chapter53/Chapter53Application.java @@ -0,0 +1,50 @@ +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; + } + + } + +} diff --git a/2.x/chapter5-3/src/main/java/com/didispace/chapter53/User.java b/2.x/chapter5-3/src/main/java/com/didispace/chapter53/User.java new file mode 100644 index 00000000..2986b7d4 --- /dev/null +++ b/2.x/chapter5-3/src/main/java/com/didispace/chapter53/User.java @@ -0,0 +1,27 @@ +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; + } +} diff --git a/2.x/chapter5-3/src/main/java/com/didispace/chapter53/UserRepository.java b/2.x/chapter5-3/src/main/java/com/didispace/chapter53/UserRepository.java new file mode 100644 index 00000000..4d52745e --- /dev/null +++ b/2.x/chapter5-3/src/main/java/com/didispace/chapter53/UserRepository.java @@ -0,0 +1,21 @@ +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); + +} diff --git a/2.x/chapter5-3/src/main/resources/application.properties b/2.x/chapter5-3/src/main/resources/application.properties new file mode 100644 index 00000000..43e74c79 --- /dev/null +++ b/2.x/chapter5-3/src/main/resources/application.properties @@ -0,0 +1,17 @@ +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 diff --git a/2.x/chapter5-3/src/main/resources/ehcache-1.xml b/2.x/chapter5-3/src/main/resources/ehcache-1.xml new file mode 100644 index 00000000..fbc88162 --- /dev/null +++ b/2.x/chapter5-3/src/main/resources/ehcache-1.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/2.x/chapter5-3/src/main/resources/ehcache-2.xml b/2.x/chapter5-3/src/main/resources/ehcache-2.xml new file mode 100644 index 00000000..878b6be2 --- /dev/null +++ b/2.x/chapter5-3/src/main/resources/ehcache-2.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/2.x/chapter5-3/src/test/java/com/didispace/chapter53/Chapter53ApplicationTests.java b/2.x/chapter5-3/src/test/java/com/didispace/chapter53/Chapter53ApplicationTests.java new file mode 100644 index 00000000..0e9c2939 --- /dev/null +++ b/2.x/chapter5-3/src/test/java/com/didispace/chapter53/Chapter53ApplicationTests.java @@ -0,0 +1,36 @@ +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()); + } + +} diff --git a/2.x/chapter5-4/.gitignore b/2.x/chapter5-4/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter5-4/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter5-4/pom.xml b/2.x/chapter5-4/pom.xml new file mode 100644 index 00000000..1f4de65e --- /dev/null +++ b/2.x/chapter5-4/pom.xml @@ -0,0 +1,75 @@ + + + 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 + + + + + diff --git a/2.x/chapter5-4/src/main/java/com/didispace/chapter54/Chapter54Application.java b/2.x/chapter5-4/src/main/java/com/didispace/chapter54/Chapter54Application.java new file mode 100644 index 00000000..f2789f8b --- /dev/null +++ b/2.x/chapter5-4/src/main/java/com/didispace/chapter54/Chapter54Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter5-4/src/main/java/com/didispace/chapter54/User.java b/2.x/chapter5-4/src/main/java/com/didispace/chapter54/User.java new file mode 100644 index 00000000..11e2dc13 --- /dev/null +++ b/2.x/chapter5-4/src/main/java/com/didispace/chapter54/User.java @@ -0,0 +1,27 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter5-4/src/main/java/com/didispace/chapter54/UserRepository.java b/2.x/chapter5-4/src/main/java/com/didispace/chapter54/UserRepository.java new file mode 100644 index 00000000..4b14b113 --- /dev/null +++ b/2.x/chapter5-4/src/main/java/com/didispace/chapter54/UserRepository.java @@ -0,0 +1,26 @@ +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); + +} diff --git a/2.x/chapter5-4/src/main/resources/application.properties b/2.x/chapter5-4/src/main/resources/application.properties new file mode 100644 index 00000000..7136291e --- /dev/null +++ b/2.x/chapter5-4/src/main/resources/application.properties @@ -0,0 +1,16 @@ +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 diff --git a/2.x/chapter5-4/src/test/java/com/didispace/chapter54/Chapter54ApplicationTests.java b/2.x/chapter5-4/src/test/java/com/didispace/chapter54/Chapter54ApplicationTests.java new file mode 100644 index 00000000..de5a7185 --- /dev/null +++ b/2.x/chapter5-4/src/test/java/com/didispace/chapter54/Chapter54ApplicationTests.java @@ -0,0 +1,36 @@ +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()); + } + +} diff --git a/2.x/chapter5-5/.gitignore b/2.x/chapter5-5/.gitignore new file mode 100644 index 00000000..153c9335 --- /dev/null +++ b/2.x/chapter5-5/.gitignore @@ -0,0 +1,29 @@ +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/ diff --git a/2.x/chapter5-5/pom.xml b/2.x/chapter5-5/pom.xml new file mode 100644 index 00000000..dc1d2874 --- /dev/null +++ b/2.x/chapter5-5/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + diff --git a/2.x/chapter5-5/src/main/java/com/didispace/chapter55/Chapter55Application.java b/2.x/chapter5-5/src/main/java/com/didispace/chapter55/Chapter55Application.java new file mode 100644 index 00000000..8da3b8b0 --- /dev/null +++ b/2.x/chapter5-5/src/main/java/com/didispace/chapter55/Chapter55Application.java @@ -0,0 +1,61 @@ +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)); + + } + + } + +} diff --git a/2.x/chapter5-5/src/main/resources/application.properties b/2.x/chapter5-5/src/main/resources/application.properties new file mode 100644 index 00000000..2992f608 --- /dev/null +++ b/2.x/chapter5-5/src/main/resources/application.properties @@ -0,0 +1,7 @@ +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 diff --git a/2.x/chapter6-1/pom.xml b/2.x/chapter6-1/pom.xml new file mode 100755 index 00000000..10a0116e --- /dev/null +++ b/2.x/chapter6-1/pom.xml @@ -0,0 +1,55 @@ + + + 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 + + + + + diff --git a/2.x/chapter6-1/src/main/java/com/didispace/chapter61/Chapter61Application.java b/2.x/chapter6-1/src/main/java/com/didispace/chapter61/Chapter61Application.java new file mode 100755 index 00000000..dfd534eb --- /dev/null +++ b/2.x/chapter6-1/src/main/java/com/didispace/chapter61/Chapter61Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter6-1/src/main/java/com/didispace/chapter61/User.java b/2.x/chapter6-1/src/main/java/com/didispace/chapter61/User.java new file mode 100644 index 00000000..e94f10c0 --- /dev/null +++ b/2.x/chapter6-1/src/main/java/com/didispace/chapter61/User.java @@ -0,0 +1,22 @@ +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; + +} diff --git a/2.x/chapter6-1/src/main/java/com/didispace/chapter61/UserRepository.java b/2.x/chapter6-1/src/main/java/com/didispace/chapter61/UserRepository.java new file mode 100644 index 00000000..f1336f96 --- /dev/null +++ b/2.x/chapter6-1/src/main/java/com/didispace/chapter61/UserRepository.java @@ -0,0 +1,14 @@ +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); + +} diff --git a/2.x/chapter6-1/src/main/resources/application.properties b/2.x/chapter6-1/src/main/resources/application.properties new file mode 100644 index 00000000..0e2f083f --- /dev/null +++ b/2.x/chapter6-1/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.data.mongodb.uri=mongodb://localhost:27017/test + + diff --git a/2.x/chapter6-1/src/test/java/com/didispace/chapter61/ApplicationTests.java b/2.x/chapter6-1/src/test/java/com/didispace/chapter61/ApplicationTests.java new file mode 100755 index 00000000..e1ee421a --- /dev/null +++ b/2.x/chapter6-1/src/test/java/com/didispace/chapter61/ApplicationTests.java @@ -0,0 +1,35 @@ +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()); + } + +} diff --git a/2.x/chapter6-2/pom.xml b/2.x/chapter6-2/pom.xml new file mode 100644 index 00000000..dc1b63bd --- /dev/null +++ b/2.x/chapter6-2/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/2.x/chapter6-2/src/main/java/com/didispace/chapter62/Chapter62Application.java b/2.x/chapter6-2/src/main/java/com/didispace/chapter62/Chapter62Application.java new file mode 100644 index 00000000..5baa9594 --- /dev/null +++ b/2.x/chapter6-2/src/main/java/com/didispace/chapter62/Chapter62Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter6-2/src/main/java/com/didispace/chapter62/Person.java b/2.x/chapter6-2/src/main/java/com/didispace/chapter62/Person.java new file mode 100644 index 00000000..cc078f67 --- /dev/null +++ b/2.x/chapter6-2/src/main/java/com/didispace/chapter62/Person.java @@ -0,0 +1,22 @@ +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; + +} diff --git a/2.x/chapter6-2/src/main/java/com/didispace/chapter62/PersonRepository.java b/2.x/chapter6-2/src/main/java/com/didispace/chapter62/PersonRepository.java new file mode 100644 index 00000000..53258324 --- /dev/null +++ b/2.x/chapter6-2/src/main/java/com/didispace/chapter62/PersonRepository.java @@ -0,0 +1,10 @@ +package com.didispace.chapter62; + +import org.springframework.data.repository.CrudRepository; + +import javax.naming.Name; + +public interface PersonRepository extends CrudRepository { + + +} \ No newline at end of file diff --git a/2.x/chapter6-2/src/main/resources/application.properties b/2.x/chapter6-2/src/main/resources/application.properties new file mode 100644 index 00000000..d2726e89 --- /dev/null +++ b/2.x/chapter6-2/src/main/resources/application.properties @@ -0,0 +1,4 @@ +#spring.ldap.urls=ldap://localhost:1235 +#spring.ldap.base=dc=didispace,dc=com +#spring.ldap.username=didispace +#spring.ldap.password=123456 diff --git a/2.x/chapter6-2/src/test/java/com/didispace/chapter62/ApplicationTests.java b/2.x/chapter6-2/src/test/java/com/didispace/chapter62/ApplicationTests.java new file mode 100644 index 00000000..b1e2a2fd --- /dev/null +++ b/2.x/chapter6-2/src/test/java/com/didispace/chapter62/ApplicationTests.java @@ -0,0 +1,38 @@ +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); + }); + } + +} diff --git a/2.x/chapter6-2/src/test/resources/application.properties b/2.x/chapter6-2/src/test/resources/application.properties new file mode 100644 index 00000000..55e19357 --- /dev/null +++ b/2.x/chapter6-2/src/test/resources/application.properties @@ -0,0 +1,3 @@ +spring.ldap.embedded.ldif=classpath:ldap-server.ldif +spring.ldap.embedded.base-dn=dc=didispace,dc=com + diff --git a/2.x/chapter6-2/src/test/resources/ldap-server.ldif b/2.x/chapter6-2/src/test/resources/ldap-server.ldif new file mode 100644 index 00000000..353a4939 --- /dev/null +++ b/2.x/chapter6-2/src/test/resources/ldap-server.ldif @@ -0,0 +1,20 @@ +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= diff --git a/2.x/chapter6-3/pom.xml b/2.x/chapter6-3/pom.xml new file mode 100644 index 00000000..686e3150 --- /dev/null +++ b/2.x/chapter6-3/pom.xml @@ -0,0 +1,59 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/2.x/chapter6-3/src/main/java/com/didispace/chapter63/Chapter63Application.java b/2.x/chapter6-3/src/main/java/com/didispace/chapter63/Chapter63Application.java new file mode 100644 index 00000000..54cc0e22 --- /dev/null +++ b/2.x/chapter6-3/src/main/java/com/didispace/chapter63/Chapter63Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter6-3/src/main/java/com/didispace/chapter63/Monitor.java b/2.x/chapter6-3/src/main/java/com/didispace/chapter63/Monitor.java new file mode 100644 index 00000000..fd62dc20 --- /dev/null +++ b/2.x/chapter6-3/src/main/java/com/didispace/chapter63/Monitor.java @@ -0,0 +1,43 @@ +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); + } + +} diff --git a/2.x/chapter6-3/src/main/resources/application.properties b/2.x/chapter6-3/src/main/resources/application.properties new file mode 100644 index 00000000..0df52b44 --- /dev/null +++ b/2.x/chapter6-3/src/main/resources/application.properties @@ -0,0 +1,5 @@ + +spring.influx.url=http://localhost:8086 +spring.influx.user=admin +spring.influx.password= + diff --git a/2.x/chapter6-3/src/test/java/com/didispace/chapter63/ApplicationTests.java b/2.x/chapter6-3/src/test/java/com/didispace/chapter63/ApplicationTests.java new file mode 100644 index 00000000..4720d3cc --- /dev/null +++ b/2.x/chapter6-3/src/test/java/com/didispace/chapter63/ApplicationTests.java @@ -0,0 +1,22 @@ +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() { + + } + +} diff --git a/2.x/chapter6-4/pom.xml b/2.x/chapter6-4/pom.xml new file mode 100644 index 00000000..c1683b06 --- /dev/null +++ b/2.x/chapter6-4/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + \ No newline at end of file diff --git a/2.x/chapter6-4/src/main/java/com/didispace/chapter64/Chapter64Application.java b/2.x/chapter6-4/src/main/java/com/didispace/chapter64/Chapter64Application.java new file mode 100644 index 00000000..83ebf477 --- /dev/null +++ b/2.x/chapter6-4/src/main/java/com/didispace/chapter64/Chapter64Application.java @@ -0,0 +1,14 @@ +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); + } + +} diff --git a/2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfo.java b/2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfo.java new file mode 100644 index 00000000..cc83d361 --- /dev/null +++ b/2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfo.java @@ -0,0 +1,26 @@ +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; + } +} \ No newline at end of file diff --git a/2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfoRepository.java b/2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfoRepository.java new file mode 100644 index 00000000..85214e24 --- /dev/null +++ b/2.x/chapter6-4/src/main/java/com/didispace/chapter64/UserInfoRepository.java @@ -0,0 +1,22 @@ +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); + +} diff --git a/2.x/chapter6-4/src/main/resources/application.properties b/2.x/chapter6-4/src/main/resources/application.properties new file mode 100644 index 00000000..3c000bf2 --- /dev/null +++ b/2.x/chapter6-4/src/main/resources/application.properties @@ -0,0 +1,7 @@ +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 \ No newline at end of file diff --git a/2.x/chapter6-4/src/test/java/com/didispace/chapter64/ApplicationTests.java b/2.x/chapter6-4/src/test/java/com/didispace/chapter64/ApplicationTests.java new file mode 100644 index 00000000..1ae64fb4 --- /dev/null +++ b/2.x/chapter6-4/src/test/java/com/didispace/chapter64/ApplicationTests.java @@ -0,0 +1,51 @@ +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()); + + } + +} diff --git a/2.x/chapter7-1/pom.xml b/2.x/chapter7-1/pom.xml new file mode 100755 index 00000000..fc9142ad --- /dev/null +++ b/2.x/chapter7-1/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-1/src/main/java/com/didispace/chapter71/Chapter71Application.java b/2.x/chapter7-1/src/main/java/com/didispace/chapter71/Chapter71Application.java new file mode 100755 index 00000000..95fd0d2d --- /dev/null +++ b/2.x/chapter7-1/src/main/java/com/didispace/chapter71/Chapter71Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter7-1/src/main/java/com/didispace/chapter71/ScheduledTasks.java b/2.x/chapter7-1/src/main/java/com/didispace/chapter71/ScheduledTasks.java new file mode 100644 index 00000000..27f1d0db --- /dev/null +++ b/2.x/chapter7-1/src/main/java/com/didispace/chapter71/ScheduledTasks.java @@ -0,0 +1,24 @@ +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())); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-1/src/main/resources/application.properties b/2.x/chapter7-1/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/2.x/chapter7-2/pom.xml b/2.x/chapter7-2/pom.xml new file mode 100755 index 00000000..e1987da5 --- /dev/null +++ b/2.x/chapter7-2/pom.xml @@ -0,0 +1,51 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-2/src/main/java/com/didispace/chapter72/Chapter72Application.java b/2.x/chapter7-2/src/main/java/com/didispace/chapter72/Chapter72Application.java new file mode 100755 index 00000000..236357d8 --- /dev/null +++ b/2.x/chapter7-2/src/main/java/com/didispace/chapter72/Chapter72Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter7-2/src/main/java/com/didispace/chapter72/MySimpleJob.java b/2.x/chapter7-2/src/main/java/com/didispace/chapter72/MySimpleJob.java new file mode 100644 index 00000000..242a8168 --- /dev/null +++ b/2.x/chapter7-2/src/main/java/com/didispace/chapter72/MySimpleJob.java @@ -0,0 +1,17 @@ +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()); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-2/src/main/resources/application.properties b/2.x/chapter7-2/src/main/resources/application.properties new file mode 100644 index 00000000..38bca408 --- /dev/null +++ b/2.x/chapter7-2/src/main/resources/application.properties @@ -0,0 +1,7 @@ + +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 diff --git a/2.x/chapter7-3/pom.xml b/2.x/chapter7-3/pom.xml new file mode 100755 index 00000000..55d4ff9f --- /dev/null +++ b/2.x/chapter7-3/pom.xml @@ -0,0 +1,51 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-3/src/main/java/com/didispace/chapter73/Chapter73Application.java b/2.x/chapter7-3/src/main/java/com/didispace/chapter73/Chapter73Application.java new file mode 100755 index 00000000..5c62c3e6 --- /dev/null +++ b/2.x/chapter7-3/src/main/java/com/didispace/chapter73/Chapter73Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter7-3/src/main/java/com/didispace/chapter73/MyShardingJob.java b/2.x/chapter7-3/src/main/java/com/didispace/chapter73/MyShardingJob.java new file mode 100644 index 00000000..d1f535ae --- /dev/null +++ b/2.x/chapter7-3/src/main/java/com/didispace/chapter73/MyShardingJob.java @@ -0,0 +1,28 @@ +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; + } + } + +} \ No newline at end of file diff --git a/2.x/chapter7-3/src/main/resources/application.properties b/2.x/chapter7-3/src/main/resources/application.properties new file mode 100644 index 00000000..cb7d3cd8 --- /dev/null +++ b/2.x/chapter7-3/src/main/resources/application.properties @@ -0,0 +1,6 @@ +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 diff --git a/2.x/chapter7-4/pom.xml b/2.x/chapter7-4/pom.xml new file mode 100755 index 00000000..5bab3842 --- /dev/null +++ b/2.x/chapter7-4/pom.xml @@ -0,0 +1,51 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-4/src/main/java/com/didispace/chapter74/Chapter74Application.java b/2.x/chapter7-4/src/main/java/com/didispace/chapter74/Chapter74Application.java new file mode 100644 index 00000000..e2674e95 --- /dev/null +++ b/2.x/chapter7-4/src/main/java/com/didispace/chapter74/Chapter74Application.java @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/2.x/chapter7-4/src/main/java/com/didispace/chapter74/MySimpleJob.java b/2.x/chapter7-4/src/main/java/com/didispace/chapter74/MySimpleJob.java new file mode 100644 index 00000000..4e651c3e --- /dev/null +++ b/2.x/chapter7-4/src/main/java/com/didispace/chapter74/MySimpleJob.java @@ -0,0 +1,17 @@ +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()); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-4/src/main/resources/application.properties b/2.x/chapter7-4/src/main/resources/application.properties new file mode 100644 index 00000000..16a59e0f --- /dev/null +++ b/2.x/chapter7-4/src/main/resources/application.properties @@ -0,0 +1,8 @@ +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 diff --git a/2.x/chapter7-5/pom.xml b/2.x/chapter7-5/pom.xml new file mode 100755 index 00000000..4ff53d56 --- /dev/null +++ b/2.x/chapter7-5/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-5/src/main/java/com/didispace/chapter75/AsyncTasks.java b/2.x/chapter7-5/src/main/java/com/didispace/chapter75/AsyncTasks.java new file mode 100644 index 00000000..e2f1be13 --- /dev/null +++ b/2.x/chapter7-5/src/main/java/com/didispace/chapter75/AsyncTasks.java @@ -0,0 +1,46 @@ +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("任务三完成"); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-5/src/main/java/com/didispace/chapter75/Chapter75Application.java b/2.x/chapter7-5/src/main/java/com/didispace/chapter75/Chapter75Application.java new file mode 100644 index 00000000..e8aef549 --- /dev/null +++ b/2.x/chapter7-5/src/main/java/com/didispace/chapter75/Chapter75Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter7-5/src/main/resources/application.properties b/2.x/chapter7-5/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/2.x/chapter7-5/src/test/java/com/didispace/chapter75/Chapter75ApplicationTests.java b/2.x/chapter7-5/src/test/java/com/didispace/chapter75/Chapter75ApplicationTests.java new file mode 100644 index 00000000..af32b972 --- /dev/null +++ b/2.x/chapter7-5/src/test/java/com/didispace/chapter75/Chapter75ApplicationTests.java @@ -0,0 +1,33 @@ +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) + "毫秒"); + } + +} diff --git a/2.x/chapter7-6/pom.xml b/2.x/chapter7-6/pom.xml new file mode 100755 index 00000000..c67956f5 --- /dev/null +++ b/2.x/chapter7-6/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-6/src/main/java/com/didispace/chapter76/AsyncTasks.java b/2.x/chapter7-6/src/main/java/com/didispace/chapter76/AsyncTasks.java new file mode 100644 index 00000000..66a01d8e --- /dev/null +++ b/2.x/chapter7-6/src/main/java/com/didispace/chapter76/AsyncTasks.java @@ -0,0 +1,47 @@ +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("任务三完成"); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-6/src/main/java/com/didispace/chapter76/Chapter76Application.java b/2.x/chapter7-6/src/main/java/com/didispace/chapter76/Chapter76Application.java new file mode 100644 index 00000000..4f856eba --- /dev/null +++ b/2.x/chapter7-6/src/main/java/com/didispace/chapter76/Chapter76Application.java @@ -0,0 +1,15 @@ +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); + } + +} diff --git a/2.x/chapter7-6/src/main/resources/application.properties b/2.x/chapter7-6/src/main/resources/application.properties new file mode 100644 index 00000000..070a4b71 --- /dev/null +++ b/2.x/chapter7-6/src/main/resources/application.properties @@ -0,0 +1,9 @@ +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 \ No newline at end of file diff --git a/2.x/chapter7-6/src/test/java/com/didispace/chapter76/Chapter76ApplicationTests.java b/2.x/chapter7-6/src/test/java/com/didispace/chapter76/Chapter76ApplicationTests.java new file mode 100644 index 00000000..2a832502 --- /dev/null +++ b/2.x/chapter7-6/src/test/java/com/didispace/chapter76/Chapter76ApplicationTests.java @@ -0,0 +1,32 @@ +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) + "毫秒"); + } + +} diff --git a/2.x/chapter7-7/pom.xml b/2.x/chapter7-7/pom.xml new file mode 100755 index 00000000..2a69afe0 --- /dev/null +++ b/2.x/chapter7-7/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-7/src/main/java/com/didispace/chapter77/AsyncTasks.java b/2.x/chapter7-7/src/main/java/com/didispace/chapter77/AsyncTasks.java new file mode 100644 index 00000000..90185dc8 --- /dev/null +++ b/2.x/chapter7-7/src/main/java/com/didispace/chapter77/AsyncTasks.java @@ -0,0 +1,36 @@ +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("任务完成"); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-7/src/main/java/com/didispace/chapter77/Chapter77Application.java b/2.x/chapter7-7/src/main/java/com/didispace/chapter77/Chapter77Application.java new file mode 100644 index 00000000..e598f26d --- /dev/null +++ b/2.x/chapter7-7/src/main/java/com/didispace/chapter77/Chapter77Application.java @@ -0,0 +1,55 @@ +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; + } + + } + +} diff --git a/2.x/chapter7-7/src/main/resources/application.properties b/2.x/chapter7-7/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/2.x/chapter7-7/src/test/java/com/didispace/chapter77/Chapter77ApplicationTests.java b/2.x/chapter7-7/src/test/java/com/didispace/chapter77/Chapter77ApplicationTests.java new file mode 100644 index 00000000..d6479787 --- /dev/null +++ b/2.x/chapter7-7/src/test/java/com/didispace/chapter77/Chapter77ApplicationTests.java @@ -0,0 +1,40 @@ +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) + "毫秒"); + } + +} diff --git a/2.x/chapter7-8/pom.xml b/2.x/chapter7-8/pom.xml new file mode 100755 index 00000000..40158a94 --- /dev/null +++ b/2.x/chapter7-8/pom.xml @@ -0,0 +1,50 @@ + + + 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 + + + + + diff --git a/2.x/chapter7-8/src/main/java/com/didispace/chapter78/AsyncTasks.java b/2.x/chapter7-8/src/main/java/com/didispace/chapter78/AsyncTasks.java new file mode 100644 index 00000000..5cb782f5 --- /dev/null +++ b/2.x/chapter7-8/src/main/java/com/didispace/chapter78/AsyncTasks.java @@ -0,0 +1,26 @@ +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("任务完成"); + } + +} \ No newline at end of file diff --git a/2.x/chapter7-8/src/main/java/com/didispace/chapter78/Chapter78Application.java b/2.x/chapter7-8/src/main/java/com/didispace/chapter78/Chapter78Application.java new file mode 100644 index 00000000..f04169be --- /dev/null +++ b/2.x/chapter7-8/src/main/java/com/didispace/chapter78/Chapter78Application.java @@ -0,0 +1,60 @@ +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; + } + + } + +} diff --git a/2.x/chapter7-8/src/main/resources/application.properties b/2.x/chapter7-8/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/2.x/chapter7-8/src/test/java/com/didispace/chapter78/Chapter78ApplicationTests.java b/2.x/chapter7-8/src/test/java/com/didispace/chapter78/Chapter78ApplicationTests.java new file mode 100644 index 00000000..6b9a3919 --- /dev/null +++ b/2.x/chapter7-8/src/test/java/com/didispace/chapter78/Chapter78ApplicationTests.java @@ -0,0 +1,61 @@ +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) + "毫秒"); + } + +} diff --git a/2.x/chapter8-1/pom.xml b/2.x/chapter8-1/pom.xml new file mode 100644 index 00000000..d60616ec --- /dev/null +++ b/2.x/chapter8-1/pom.xml @@ -0,0 +1,54 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/2.x/chapter8-1/src/main/java/com/didispace/chapter81/Chapter81Application.java b/2.x/chapter8-1/src/main/java/com/didispace/chapter81/Chapter81Application.java new file mode 100644 index 00000000..a8fec0e0 --- /dev/null +++ b/2.x/chapter8-1/src/main/java/com/didispace/chapter81/Chapter81Application.java @@ -0,0 +1,26 @@ +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"); + } + +} diff --git a/2.x/chapter8-1/src/main/resources/application.properties b/2.x/chapter8-1/src/main/resources/application.properties new file mode 100644 index 00000000..361847c5 --- /dev/null +++ b/2.x/chapter8-1/src/main/resources/application.properties @@ -0,0 +1,14 @@ +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 diff --git a/2.x/chapter8-2/pom.xml b/2.x/chapter8-2/pom.xml new file mode 100644 index 00000000..eeda9143 --- /dev/null +++ b/2.x/chapter8-2/pom.xml @@ -0,0 +1,65 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/2.x/chapter8-2/src/main/java/com/didispace/chapter82/Chapter82Application.java b/2.x/chapter8-2/src/main/java/com/didispace/chapter82/Chapter82Application.java new file mode 100644 index 00000000..be62c0c2 --- /dev/null +++ b/2.x/chapter8-2/src/main/java/com/didispace/chapter82/Chapter82Application.java @@ -0,0 +1,26 @@ +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"); + } + +} diff --git a/2.x/chapter8-2/src/main/resources/application.properties b/2.x/chapter8-2/src/main/resources/application.properties new file mode 100644 index 00000000..b642e6f9 --- /dev/null +++ b/2.x/chapter8-2/src/main/resources/application.properties @@ -0,0 +1,2 @@ + +logging.config=classpath:log4j2.xml \ No newline at end of file diff --git a/2.x/chapter8-2/src/main/resources/log4j2.xml b/2.x/chapter8-2/src/main/resources/log4j2.xml new file mode 100644 index 00000000..18ca1279 --- /dev/null +++ b/2.x/chapter8-2/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/2.x/chapter8-3/pom.xml b/2.x/chapter8-3/pom.xml new file mode 100644 index 00000000..d6a578e8 --- /dev/null +++ b/2.x/chapter8-3/pom.xml @@ -0,0 +1,81 @@ + + + 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 + + + + + + \ No newline at end of file diff --git a/2.x/chapter8-3/src/main/java/com/didispace/chapter83/Chapter83Application.java b/2.x/chapter8-3/src/main/java/com/didispace/chapter83/Chapter83Application.java new file mode 100644 index 00000000..8a68d462 --- /dev/null +++ b/2.x/chapter8-3/src/main/java/com/didispace/chapter83/Chapter83Application.java @@ -0,0 +1,26 @@ +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"); + } + +} diff --git a/2.x/chapter8-3/src/main/resources/application.properties b/2.x/chapter8-3/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/2.x/chapter8-3/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/2.x/chapter8-3/src/main/resources/tinylog.properties b/2.x/chapter8-3/src/main/resources/tinylog.properties new file mode 100644 index 00000000..9eb1b999 --- /dev/null +++ b/2.x/chapter8-3/src/main/resources/tinylog.properties @@ -0,0 +1,2 @@ +writer=console +writer.format={date: HH:mm:ss.SSS} {level}: {message} \ No newline at end of file diff --git a/2.x/pom.xml b/2.x/pom.xml new file mode 100644 index 00000000..f20e1714 --- /dev/null +++ b/2.x/pom.xml @@ -0,0 +1,94 @@ + + + 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 + + + + + + diff --git a/README.md b/README.md index f74734d1..916c7fa4 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,37 @@ # Spring Boot基础教程 -本项目内容为[《Spring Boot基础教程》](http://blog.didispace.com/Spring-Boot%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/)的程序样例。 - **专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程! **如何支持**: + 1. 关注我的公众号”**程序猿DD**“ 2. 点个`Star`并`Follow`我 3. 把该仓库分享给更多的朋友 -如果您对文字类教程不感冒或者想要通过综合案例学习Spring,那么给您推荐这个我觉得目前内容与价格最良心的视频课程:["玩转Spring全家桶"](https://time.geekbang.org/course/intro/156?code=d1se%2F7ugeBEyuU%2FIYp1ynYzzGDAKYLFWk96zyObvTyU%3D&utm_term=zeusEN8Q0&utm_source=git&utm_medium=chengxuyuandd&utm_campaign=156-onsell&utm_content=ddboke) +**加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长 + +**Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章 ## 教程目录 -- [Spring Boot 1.x版本教程:1.x分支](../../tree/1.x) -- [Spring Boot 2.x版本教程:2.x分支](../../tree/2.x) +该教程自2016年连载至今,因内容较多,经历过多个版本的迭代。 -> **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
+为方便查看学习,这里重新做了整理,根据1.x版本和2.x版本做了区分汇总,后续还会继续跟进3.x版本! + +可以通过下面的链接,进入具体版本的教程目录: -## 特别赞助商 - - - - - - - - -
- - - - - - - -
- -> 如果您也想赞助支持并出现在上表中的话,可以通过邮件联系我:`didi@didispace.com` - -- [阿里云:ECS云服务器2折起](https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=wxfqkr0o&utm_source=wxfqkr0o) -- [腾讯云:轻松应对建站成本问题](https://cloud.tencent.com/redirect.php?redirect=1027&cps_key=f6a8af1297bfac40b9d10ffa1270029a&from=console) +- [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):聊聊技术人的斜杠生活 -- [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基础教程 -## 我的公众号 +**关注公众号,获得更多技术资讯** - -## 我出版的书 - -![输入图片说明](https://git.oschina.net/uploads/images/2017/0416/233656_dd3bce94_437188.png "在这里输入图片标题") diff --git a/README_zh.md b/README_zh.md index d4b67348..f75927c3 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,56 +1,37 @@ # Spring Boot基础教程 -本项目内容为[《Spring Boot基础教程》](http://blog.didispace.com/Spring-Boot%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/)的程序样例。 - **专题目标**:打造全网内容最全,比收费教程更好的Spring Boot免费教程! **如何支持**: + 1. 关注我的公众号”**程序猿DD**“ 2. 点个`Star`并`Follow`我 3. 把该仓库分享给更多的朋友 -如果您对文字类教程不感冒或者想要通过综合案例学习Spring,那么给您推荐这个我觉得目前内容与价格最良心的视频课程:["玩转Spring全家桶"](https://time.geekbang.org/course/intro/156?code=d1se%2F7ugeBEyuU%2FIYp1ynYzzGDAKYLFWk96zyObvTyU%3D&utm_term=zeusEN8Q0&utm_source=git&utm_medium=chengxuyuandd&utm_campaign=156-onsell&utm_content=ddboke) +**加入社群**:如果你正在学习Spring Boot,不妨加入我们的[Spring技术交流群](https://blog.didispace.com/join-group-spring/index.html) ,一起成长 -## 教程目录 +**Spring社区**:如果您在学习过程中碰到问题,可以访问[SpringForAll社区](http://spring4all.com),描述你的问题,我们会尽快给你答复。当然,如果你想分享你的学习经验,也可以在这里发表你的文章 -- [Spring Boot 1.x版本教程:1.x分支](../../tree/1.x) -- [Spring Boot 2.x版本教程:2.x分支](../../tree/2.x) +## 教程目录 -> **关注公众号:“程序猿DD”**,领取我整理的免费学习资料。
+该教程自2016年连载至今,因内容较多,经历过多个版本的迭代。 -## 特别赞助商 +为方便查看学习,这里重新做了整理,根据1.x版本和2.x版本做了区分汇总。 - - - - - - -
- - - -
+可以通过下面的链接,进入具体版本的教程目录: -> 如果您也想赞助支持并出现在上表中的话,可以通过邮件联系我:`didi@didispace.com` +- [Spring Boot 2.x](./2.x) +- [Spring Boot 1.x](./1.x) -- [阿里云:ECS云服务器2折起](https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=wxfqkr0o&utm_source=wxfqkr0o) -- [腾讯云:轻松应对建站成本问题](https://cloud.tencent.com/redirect.php?redirect=1027&cps_key=f6a8af1297bfac40b9d10ffa1270029a&from=console) +> **关注公众号:“程序猿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):聊聊技术人的斜杠生活 -- [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基础教程 -## 我的公众号 +**关注公众号,获得更多技术资讯** - -## 我出版的书 - -![输入图片说明](https://git.oschina.net/uploads/images/2017/0416/233656_dd3bce94_437188.png "在这里输入图片标题") diff --git a/images/gitee/001.jpg b/images/gitee/001.jpg new file mode 100644 index 00000000..01347f5e Binary files /dev/null and b/images/gitee/001.jpg differ diff --git a/images/gitee/002.jpg b/images/gitee/002.jpg new file mode 100644 index 00000000..6bfd55a9 Binary files /dev/null and b/images/gitee/002.jpg differ diff --git a/images/gitee/003.jpg b/images/gitee/003.jpg new file mode 100644 index 00000000..16e904be Binary files /dev/null and b/images/gitee/003.jpg differ diff --git a/images/gitee/004.jpg b/images/gitee/004.jpg new file mode 100644 index 00000000..de9a1f04 Binary files /dev/null and b/images/gitee/004.jpg differ diff --git a/images/gitee/005.jpg b/images/gitee/005.jpg new file mode 100644 index 00000000..60ae9470 Binary files /dev/null and b/images/gitee/005.jpg differ diff --git a/images/github/001.jpg b/images/github/001.jpg new file mode 100644 index 00000000..de9a1f04 Binary files /dev/null and b/images/github/001.jpg differ diff --git a/images/github/002.jpg b/images/github/002.jpg new file mode 100644 index 00000000..6bfd55a9 Binary files /dev/null and b/images/github/002.jpg differ diff --git a/images/github/003.jpg b/images/github/003.jpg new file mode 100644 index 00000000..60ae9470 Binary files /dev/null and b/images/github/003.jpg differ diff --git a/images/github/004.jpg b/images/github/004.jpg new file mode 100644 index 00000000..39cf81d2 Binary files /dev/null and b/images/github/004.jpg differ diff --git a/images/github/005.jpg b/images/github/005.jpg new file mode 100644 index 00000000..16e904be Binary files /dev/null and b/images/github/005.jpg differ diff --git a/images/weixin.jpg b/images/weixin.jpg new file mode 100644 index 00000000..ccfef46f Binary files /dev/null and b/images/weixin.jpg differ diff --git a/pom.xml b/pom.xml index f24e0681..469fe5a3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.didispace - SpringCloud-Learning + SpringBoot-Learning 1.0-SNAPSHOT + pom - Chapter3-1-8 - + + 2.x - diff --git a/sponsor/git-springboot-sponsor-1-500X166.jpg b/sponsor/git-springboot-sponsor-1-500X166.jpg deleted file mode 100644 index d4bd54aa..00000000 Binary files a/sponsor/git-springboot-sponsor-1-500X166.jpg and /dev/null differ diff --git a/sponsor/git-springboot-sponsor-2-300x100.jpg b/sponsor/git-springboot-sponsor-2-300x100.jpg deleted file mode 100644 index 404992d7..00000000 Binary files a/sponsor/git-springboot-sponsor-2-300x100.jpg and /dev/null differ diff --git a/sponsor/git-springboot-sponsor-3-520x120.jpg b/sponsor/git-springboot-sponsor-3-520x120.jpg deleted file mode 100755 index 248880f2..00000000 Binary files a/sponsor/git-springboot-sponsor-3-520x120.jpg and /dev/null differ