diff --git a/Chapter2-1-2/pom.xml b/Chapter2-1-2/pom.xml new file mode 100644 index 00000000..f869ccfc --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/Application.java b/Chapter2-1-2/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..bcfd43a8 --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/ApplicationEnvironmentPreparedEventListener.java b/Chapter2-1-2/src/main/java/com/didispace/ApplicationEnvironmentPreparedEventListener.java new file mode 100644 index 00000000..da2a47cb --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/ApplicationFailedEventListener.java b/Chapter2-1-2/src/main/java/com/didispace/ApplicationFailedEventListener.java new file mode 100644 index 00000000..457ff47f --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/ApplicationPreparedEventListener.java b/Chapter2-1-2/src/main/java/com/didispace/ApplicationPreparedEventListener.java new file mode 100644 index 00000000..5b529617 --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/ApplicationReadyEventListener.java b/Chapter2-1-2/src/main/java/com/didispace/ApplicationReadyEventListener.java new file mode 100644 index 00000000..9193a750 --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartedEventListener.java b/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartedEventListener.java new file mode 100644 index 00000000..3b47eba6 --- /dev/null +++ b/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/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartingEventListener.java b/Chapter2-1-2/src/main/java/com/didispace/ApplicationStartingEventListener.java new file mode 100644 index 00000000..effcb14f --- /dev/null +++ b/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/Chapter2-1-2/src/main/resources/META-INF/spring.factories b/Chapter2-1-2/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..15177da6 --- /dev/null +++ b/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/Chapter2-1-2/src/main/resources/application.properties b/Chapter2-1-2/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/Chapter2-2-1/pom.xml b/Chapter2-2-1/pom.xml new file mode 100644 index 00000000..c7eddd26 --- /dev/null +++ b/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/Chapter2-2-1/src/main/java/com/didispace/Application.java b/Chapter2-2-1/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..f06a4a25 --- /dev/null +++ b/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/Chapter2-2-1/src/main/java/com/didispace/FooProperties.java b/Chapter2-2-1/src/main/java/com/didispace/FooProperties.java new file mode 100644 index 00000000..9fdf6e22 --- /dev/null +++ b/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/Chapter2-2-1/src/main/java/com/didispace/PostInfo.java b/Chapter2-2-1/src/main/java/com/didispace/PostInfo.java new file mode 100644 index 00000000..6df554fe --- /dev/null +++ b/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/Chapter2-2-1/src/main/resources/application.properties b/Chapter2-2-1/src/main/resources/application.properties new file mode 100755 index 00000000..df1d5f5a --- /dev/null +++ b/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/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java b/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java index 1a504faf..3363bfd9 100755 --- a/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java +++ b/Chapter3-1-5/src/main/java/com/didispace/web/UserController.java @@ -36,7 +36,7 @@ public String postUser(@RequestBody User user) { } @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") - @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long") + @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); @@ -44,7 +44,7 @@ public User getUser(@PathVariable Long id) { @ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long"), + @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) @@ -57,7 +57,7 @@ public String putUser(@PathVariable Long id, @RequestBody User user) { } @ApiOperation(value="删除用户", notes="根据url的id来指定删除对象") - @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long") + @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); diff --git a/Chapter3-1-7/pom.xml b/Chapter3-1-7/pom.xml new file mode 100644 index 00000000..660637b3 --- /dev/null +++ b/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/Chapter3-1-7/src/main/java/com/didispace/Application.java b/Chapter3-1-7/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..7ac57d25 --- /dev/null +++ b/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/Chapter3-1-7/src/main/resources/application.properties b/Chapter3-1-7/src/main/resources/application.properties new file mode 100755 index 00000000..e69de29b diff --git a/Chapter3-2-11/pom.xml b/Chapter3-2-11/pom.xml new file mode 100755 index 00000000..d9ac4cf1 --- /dev/null +++ b/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/Chapter3-2-11/src/main/java/com/didispace/Application.java b/Chapter3-2-11/src/main/java/com/didispace/Application.java new file mode 100755 index 00000000..89042041 --- /dev/null +++ b/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/Chapter3-2-11/src/main/resources/application.properties b/Chapter3-2-11/src/main/resources/application.properties new file mode 100644 index 00000000..e3f19a14 --- /dev/null +++ b/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/Chapter3-2-11/src/test/java/com/didispace/ApplicationTests.java b/Chapter3-2-11/src/test/java/com/didispace/ApplicationTests.java new file mode 100755 index 00000000..b3671364 --- /dev/null +++ b/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/Chapter4-1-3/pom.xml b/Chapter4-1-3/pom.xml new file mode 100644 index 00000000..b72b7802 --- /dev/null +++ b/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/Chapter4-1-3/src/main/java/com/didispace/Application.java b/Chapter4-1-3/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..84d84ef2 --- /dev/null +++ b/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/Chapter4-1-3/src/main/java/com/didispace/async/Task.java b/Chapter4-1-3/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..07891f82 --- /dev/null +++ b/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/Chapter4-1-3/src/main/resources/application.properties b/Chapter4-1-3/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/Chapter4-1-3/src/test/java/com/didispace/ApplicationTests.java b/Chapter4-1-3/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..03d3fab7 --- /dev/null +++ b/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/Chapter4-1-4/pom.xml b/Chapter4-1-4/pom.xml new file mode 100644 index 00000000..c8b4be29 --- /dev/null +++ b/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/Chapter4-1-4/src/main/java/com/didispace/Application.java b/Chapter4-1-4/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..5de0f631 --- /dev/null +++ b/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/Chapter4-1-4/src/main/java/com/didispace/async/Task.java b/Chapter4-1-4/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..ac0b102c --- /dev/null +++ b/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/Chapter4-1-4/src/main/resources/application.properties b/Chapter4-1-4/src/main/resources/application.properties new file mode 100644 index 00000000..806eddf3 --- /dev/null +++ b/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/Chapter4-1-4/src/test/java/com/didispace/ApplicationTests.java b/Chapter4-1-4/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..61107f29 --- /dev/null +++ b/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/Chapter4-1-5/pom.xml b/Chapter4-1-5/pom.xml new file mode 100644 index 00000000..524627d6 --- /dev/null +++ b/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/Chapter4-1-5/src/main/java/com/didispace/Application.java b/Chapter4-1-5/src/main/java/com/didispace/Application.java new file mode 100644 index 00000000..84d84ef2 --- /dev/null +++ b/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/Chapter4-1-5/src/main/java/com/didispace/async/Task.java b/Chapter4-1-5/src/main/java/com/didispace/async/Task.java new file mode 100644 index 00000000..49f5f7e0 --- /dev/null +++ b/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/Chapter4-1-5/src/main/resources/application.properties b/Chapter4-1-5/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/Chapter4-1-5/src/test/java/com/didispace/ApplicationTests.java b/Chapter4-1-5/src/test/java/com/didispace/ApplicationTests.java new file mode 100644 index 00000000..c9cd12fd --- /dev/null +++ b/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/Chapter4-4-2/src/main/resources/application.properties b/Chapter4-4-2/src/main/resources/application.properties index 1a9d0255..248f22c4 100644 --- a/Chapter4-4-2/src/main/resources/application.properties +++ b/Chapter4-4-2/src/main/resources/application.properties @@ -3,6 +3,7 @@ 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 diff --git a/README.md b/README.md index 0acc6f5a..ec90bff8 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,30 @@ - GitHub:https://github.com/dyc87112/SpringBoot-Learning - Gitee:https://gitee.com/didispace/SpringBoot-Learning - Spring For All社区:http://spring4all.com/ -- Spring Boot系列博文:http://blog.didispace.com/categories/Spring-Boot/ -- Spring Cloud系列博文:http://blog.didispace.com/categories/Spring-Cloud/ +- Spring Boot基础教程:http://blog.didispace.com/Spring-Boot%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/ +- Spring Cloud基础教程:http://blog.didispace.com/Spring-Cloud%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/ **声明:本人已放弃"Spring Cloud中国社区",该社区的任何行为均与本人无关。[Spring For All社区](http://spring4all.com/)是新组建的关于Spring的纯技术交流社区(涵盖Spring Boot、Spring Cloud等内容),集诸多开源爱好者和技术大牛贡献内容和交流问题。我们不夸大、不装逼、做最纯粹的技术分享!!!** -## 样例列表 +**优惠云服务推荐** + +- [腾讯云:3年时长最低265元/年](https://cloud.tencent.com/redirect.php?redirect=1005&cps_key=f6a8af1297bfac40b9d10ffa1270029a) +- [阿里云:ECS云服务器2折起](https://s.click.taobao.com/t?e=m%3D2%26s%3Dzj4kbQ5lKukcQipKwQzePCperVdZeJviEViQ0P1Vf2kguMN8XjClAq9GNeKfy2AD4SaRmc4YmqYCxNLxWxqxDPY8Eqzf%2BUWbOTauL6DcROffvu81lbXO1DDVuRn8ddiDsEVVC24eqozO54LQ%2FVw1L9X5LHh3Z8M%2BWS6ALZVeqlk9XUfbPSJC%2F06deTzTIbffYpyF7ku%2BxKgGargQjSAC4C6cUF%2FXAmem) + +## Spring Boot 2.0 新特性学习 + +**简介与概览** + +- [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/) + +## Spring Boot 基础教程(基于1.3.x-1.5.x) #### 快速入门 @@ -22,6 +40,8 @@ #### 工程配置 - chapter2-1-1:[配置文件详解:自定义属性、随机数、多环境配置等](http://blog.didispace.com/springbootproperties/) +- chapter2-1-2:[2.0 新特性(一):配置绑定全解析](http://blog.didispace.com/Spring-Boot-2-0-feature-1-relaxed-binding-2/) +- chapter2-2-1:[2.0 新特性(二):新增事件ApplicationStartedEvent](http://blog.didispace.com/Spring-Boot-2-0-feature-2-ApplicationStartedEvent/) #### Web开发 @@ -44,6 +64,7 @@ - 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/) #### 事务管理 @@ -51,8 +72,12 @@ - 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/) #### 日志管理