├── product ├── server │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── geekerstar │ │ │ │ │ └── product │ │ │ │ │ ├── service │ │ │ │ │ ├── ProductService.java │ │ │ │ │ ├── impl │ │ │ │ │ │ ├── CategoryServiceImpl.java │ │ │ │ │ │ └── ProductServiceImpl.java │ │ │ │ │ └── CategoryService.java │ │ │ │ │ ├── VO │ │ │ │ │ ├── ResultVO.java │ │ │ │ │ ├── ProductVO.java │ │ │ │ │ └── ProductInfoVO.java │ │ │ │ │ ├── controller │ │ │ │ │ ├── ServerController.java │ │ │ │ │ └── ProductController.java │ │ │ │ │ ├── utils │ │ │ │ │ ├── ResultVOUtil.java │ │ │ │ │ └── JsonUtil.java │ │ │ │ │ ├── ProductApplication.java │ │ │ │ │ ├── enums │ │ │ │ │ ├── ProductStatusEnum.java │ │ │ │ │ └── ResultEnum.java │ │ │ │ │ ├── repository │ │ │ │ │ ├── ProductCategoryRepository.java │ │ │ │ │ └── ProductInfoRepository.java │ │ │ │ │ ├── exception │ │ │ │ │ └── ProductException.java │ │ │ │ │ └── dataobject │ │ │ │ │ ├── ProductCategory.java │ │ │ │ │ └── ProductInfo.java │ │ │ └── resources │ │ │ │ └── bootstrap.yml │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── geekerstar │ │ │ └── product │ │ │ ├── ProductApplicationTests.java │ │ │ ├── service │ │ │ ├── CategoryServiceTest.java │ │ │ └── ProductServiceTest.java │ │ │ └── repository │ │ │ ├── ProductCategoryRepositoryTest.java │ │ │ └── ProductInfoRepositoryTest.java │ └── pom.xml ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── Dockerfile ├── build.sh ├── .gitignore ├── common │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── geekerstar │ │ │ └── product │ │ │ └── common │ │ │ ├── DecreaseStockInput.java │ │ │ └── ProductInfoOutput.java │ └── pom.xml ├── client │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── geekerstar │ │ └── product │ │ └── client │ │ └── ProductClient.java └── pom.xml ├── eureka ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.yml │ │ │ ├── application-eureka1.yml │ │ │ └── application-eureka2.yml │ │ └── java │ │ │ └── com │ │ │ └── geekerstar │ │ │ └── eureka │ │ │ └── EurekaApplication.java │ └── test │ │ └── java │ │ └── com │ │ └── geekerstar │ │ └── eureka │ │ └── EurekaApplicationTests.java ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── .gitignore ├── pom.xml ├── mvnw.cmd └── mvnw ├── img ├── 1.jpg ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 2.png ├── 20.png ├── 21.jpg ├── 22.jpg ├── 23.png ├── 24.jpg ├── 25.jpg ├── 26.jpg ├── 27.jpg ├── 3.png ├── 4.png ├── 5.jpg ├── 6.png ├── 7.png ├── 8.png └── 9.jpg ├── config └── src │ ├── test │ └── java │ │ └── com │ │ └── imooc │ │ └── config │ │ └── ConfigApplicationTests.java │ └── main │ ├── resources │ └── application.yml │ └── java │ └── com │ └── geekerstar │ └── config │ └── ConfigApplication.java ├── .gitignore └── README.md /product/server/src/main/java/com/geekerstar/product/service/ProductService.java: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /eureka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: eureka1 -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/1.jpg -------------------------------------------------------------------------------- /img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/10.png -------------------------------------------------------------------------------- /img/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/11.png -------------------------------------------------------------------------------- /img/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/12.png -------------------------------------------------------------------------------- /img/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/13.png -------------------------------------------------------------------------------- /img/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/14.png -------------------------------------------------------------------------------- /img/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/15.png -------------------------------------------------------------------------------- /img/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/16.png -------------------------------------------------------------------------------- /img/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/17.png -------------------------------------------------------------------------------- /img/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/18.png -------------------------------------------------------------------------------- /img/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/19.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/2.png -------------------------------------------------------------------------------- /img/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/20.png -------------------------------------------------------------------------------- /img/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/21.jpg -------------------------------------------------------------------------------- /img/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/22.jpg -------------------------------------------------------------------------------- /img/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/23.png -------------------------------------------------------------------------------- /img/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/24.jpg -------------------------------------------------------------------------------- /img/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/25.jpg -------------------------------------------------------------------------------- /img/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/26.jpg -------------------------------------------------------------------------------- /img/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/27.jpg -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/4.png -------------------------------------------------------------------------------- /img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/5.jpg -------------------------------------------------------------------------------- /img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/6.png -------------------------------------------------------------------------------- /img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/7.png -------------------------------------------------------------------------------- /img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/8.png -------------------------------------------------------------------------------- /img/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/img/9.jpg -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/service/impl/CategoryServiceImpl.java: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /eureka/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/eureka/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /product/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geekerstar/dive-in-springcloud/HEAD/product/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /eureka/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /product/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip 2 | -------------------------------------------------------------------------------- /product/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:8-alpine 2 | 3 | MAINTAINER XXX XXX@imooc.com 4 | 5 | ADD server/target/*.jar app.jar 6 | 7 | EXPOSE 8080 8 | 9 | ENTRYPOINT ["java", "-jar", "/app.jar"] -------------------------------------------------------------------------------- /product/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mvn clean package -Dmaven.test.skip=true -U 4 | 5 | docker build -t hub.c.163.com/springcloud/product . 6 | 7 | docker push hub.c.163.com/springcloud/product -------------------------------------------------------------------------------- /eureka/src/main/resources/application-eureka1.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | service-url: 4 | defaultZone: http://eureka2:8762/eureka/ 5 | # register-with-eureka: false 6 | server: 7 | enable-self-preservation: false 8 | spring: 9 | application: 10 | name: eureka 11 | server: 12 | port: 8761 13 | -------------------------------------------------------------------------------- /eureka/src/main/resources/application-eureka2.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | client: 3 | service-url: 4 | defaultZone: http://eureka1:8761/eureka/ 5 | # register-with-eureka: false 6 | server: 7 | enable-self-preservation: false 8 | spring: 9 | application: 10 | name: eureka 11 | server: 12 | port: 8762 13 | -------------------------------------------------------------------------------- /eureka/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /nbbuild/ 22 | /dist/ 23 | /nbdist/ 24 | /.nb-gradle/ 25 | /build/ 26 | -------------------------------------------------------------------------------- /product/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /nbbuild/ 22 | /dist/ 23 | /nbdist/ 24 | /.nb-gradle/ 25 | /build/ 26 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/service/CategoryService.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.service; 2 | 3 | import com.geekerstar.product.dataobject.ProductCategory; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 类目 9 | * Created by 廖师兄 10 | * 2017-12-09 22:06 11 | */ 12 | public interface CategoryService { 13 | 14 | List findByCategoryTypeIn(List categoryTypeList); 15 | } 16 | -------------------------------------------------------------------------------- /config/src/test/java/com/imooc/config/ConfigApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.imooc.config; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ConfigApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /product/server/src/test/java/com/geekerstar/product/ProductApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ProductApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /eureka/src/test/java/com/geekerstar/eureka/EurekaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.eureka; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class EurekaApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /product/server/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: product 4 | cloud: 5 | config: 6 | discovery: 7 | enabled: true 8 | service-id: CONFIG 9 | profile: dev 10 | eureka: 11 | client: 12 | service-url: 13 | defaultZone: http://eureka1:8761/eureka/,http://eureka2:8762/eureka/ 14 | instance: 15 | prefer-ip-address: true 16 | 17 | logging: 18 | level: 19 | org.springframework.cloud.netflix.feign: debug -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/VO/ResultVO.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.VO; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * http请求返回的最外层对象 7 | * Created by 廖师兄 8 | * 2017-12-09 22:09 9 | */ 10 | @Data 11 | public class ResultVO { 12 | 13 | /** 14 | * 错误码 15 | */ 16 | private Integer code; 17 | 18 | /** 19 | * 提示信息 20 | */ 21 | private String msg; 22 | 23 | /** 24 | * 具体内容 25 | */ 26 | private T data; 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.nar 19 | *.ear 20 | *.zip 21 | *.tar.gz 22 | *.rar 23 | 24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | .idea 27 | dive-in-springcloud.iml 28 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/controller/ServerController.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.controller; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | * Created by 廖师兄 8 | * 2017-12-10 20:37 9 | */ 10 | @RestController 11 | public class ServerController { 12 | 13 | @GetMapping("/msg") 14 | public String msg() { 15 | return "this is product' msg"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/utils/ResultVOUtil.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.utils; 2 | 3 | import com.geekerstar.product.VO.ResultVO; 4 | 5 | /** 6 | * Created by 廖师兄 7 | * 2017-12-09 22:53 8 | */ 9 | public class ResultVOUtil { 10 | 11 | public static ResultVO success(Object object) { 12 | ResultVO resultVO = new ResultVO(); 13 | resultVO.setData(object); 14 | resultVO.setCode(0); 15 | resultVO.setMsg("成功"); 16 | return resultVO; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/ProductApplication.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class ProductApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(ProductApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /eureka/src/main/java/com/geekerstar/eureka/EurekaApplication.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.eureka; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class EurekaApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(EurekaApplication.class, args); 13 | } 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/enums/ProductStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * 商品上下架状态 7 | * Created by 廖师兄 8 | * 2017-12-09 22:00 9 | */ 10 | @Getter 11 | public enum ProductStatusEnum { 12 | UP(0, "在架"), 13 | DOWN(1, "下架"), 14 | ; 15 | 16 | private Integer code; 17 | 18 | private String message; 19 | 20 | ProductStatusEnum(Integer code, String message) { 21 | this.code = code; 22 | this.message = message; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/enums/ResultEnum.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * Created by 廖师兄 7 | * 2017-12-10 23:00 8 | */ 9 | @Getter 10 | public enum ResultEnum { 11 | 12 | PRODUCT_NOT_EXIST(1, "商品不存在"), 13 | PRODUCT_STOCK_ERROR(2, "库存有误"), 14 | ; 15 | 16 | private Integer code; 17 | 18 | private String message; 19 | 20 | ResultEnum(Integer code, String message) { 21 | this.code = code; 22 | this.message = message; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/repository/ProductCategoryRepository.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.repository; 2 | 3 | import com.geekerstar.product.dataobject.ProductCategory; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by 廖师兄 10 | * 2017-12-09 21:41 11 | */ 12 | public interface ProductCategoryRepository extends JpaRepository { 13 | 14 | List findByCategoryTypeIn(List categoryTypeList); 15 | } 16 | -------------------------------------------------------------------------------- /config/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: config 4 | cloud: 5 | config: 6 | server: 7 | git: 8 | uri: https://gitlab-demo.com/SpringCloud_Sell/config-repo.git 9 | username: lly835@163.com 10 | password: nKfm9JMUfWEh 11 | # basedir: /Users/admin/code/myProjects/java/imooc/SpringCloud_Sell/config/basedir 12 | eureka: 13 | client: 14 | service-url: 15 | defaultZone: http://localhost:8761/eureka/ 16 | management: 17 | endpoints: 18 | web: 19 | expose: "*" -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/VO/ProductVO.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.VO; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by 廖师兄 10 | * 2017-12-09 22:11 11 | */ 12 | @Data 13 | public class ProductVO { 14 | 15 | @JsonProperty("name") 16 | private String categoryName; 17 | 18 | @JsonProperty("type") 19 | private Integer categoryType; 20 | 21 | @JsonProperty("foods") 22 | List productInfoVOList; 23 | } 24 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/repository/ProductInfoRepository.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.repository; 2 | 3 | import com.geekerstar.product.dataobject.ProductInfo; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by 廖师兄 10 | * 2017-12-09 21:29 11 | */ 12 | public interface ProductInfoRepository extends JpaRepository{ 13 | 14 | List findByProductStatus(Integer productStatus); 15 | 16 | List findByProductIdIn(List productIdList); 17 | } 18 | -------------------------------------------------------------------------------- /product/common/src/main/java/com/geekerstar/product/common/DecreaseStockInput.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.common; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 减库存入参 7 | * Created by 廖师兄 8 | * 2018-01-20 22:50 9 | */ 10 | @Data 11 | public class DecreaseStockInput { 12 | 13 | private String productId; 14 | 15 | private Integer productQuantity; 16 | 17 | public DecreaseStockInput() { 18 | } 19 | 20 | public DecreaseStockInput(String productId, Integer productQuantity) { 21 | this.productId = productId; 22 | this.productQuantity = productQuantity; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /config/src/main/java/com/geekerstar/config/ConfigApplication.java: -------------------------------------------------------------------------------- 1 | package com.imooc.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.config.server.EnableConfigServer; 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @EnableConfigServer 11 | public class ConfigApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(ConfigApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/exception/ProductException.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.exception; 2 | 3 | import com.geekerstar.product.enums.ResultEnum; 4 | 5 | /** 6 | * Created by 廖师兄 7 | * 2017-12-10 22:59 8 | */ 9 | public class ProductException extends RuntimeException { 10 | 11 | private Integer code; 12 | 13 | public ProductException(Integer code, String message) { 14 | super(message); 15 | this.code = code; 16 | } 17 | 18 | public ProductException(ResultEnum resultEnum) { 19 | super(resultEnum.getMessage()); 20 | this.code = resultEnum.getCode(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/utils/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.utils; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | 6 | /** 7 | * Created by 廖师兄 8 | * 2018-02-21 10:40 9 | */ 10 | public class JsonUtil { 11 | 12 | private static ObjectMapper objectMapper = new ObjectMapper(); 13 | 14 | /** 15 | * 转换为json字符串 16 | * @param object 17 | * @return 18 | */ 19 | public static String toJson(Object object) { 20 | try { 21 | return objectMapper.writeValueAsString(object); 22 | } catch (JsonProcessingException e) { 23 | e.printStackTrace(); 24 | } 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/dataobject/ProductCategory.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.dataobject; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import java.util.Date; 9 | 10 | /** 11 | * Created by 廖师兄 12 | * 2017-12-09 21:37 13 | */ 14 | @Data 15 | @Entity 16 | public class ProductCategory { 17 | 18 | @Id 19 | @GeneratedValue 20 | private Integer categoryId; 21 | 22 | /** 类目名字. */ 23 | private String categoryName; 24 | 25 | /** 类目编号. */ 26 | private Integer categoryType; 27 | 28 | private Date createTime; 29 | 30 | private Date updateTime; 31 | } 32 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/VO/ProductInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.VO; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | import java.math.BigDecimal; 7 | 8 | /** 9 | * Created by 廖师兄 10 | * 2017-12-09 22:14 11 | */ 12 | @Data 13 | public class ProductInfoVO { 14 | 15 | @JsonProperty("id") 16 | private String productId; 17 | 18 | @JsonProperty("name") 19 | private String productName; 20 | 21 | @JsonProperty("price") 22 | private BigDecimal productPrice; 23 | 24 | @JsonProperty("description") 25 | private String productDescription; 26 | 27 | @JsonProperty("icon") 28 | private String productIcon; 29 | } 30 | -------------------------------------------------------------------------------- /product/common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | product 7 | com.geekerstar 8 | 0.0.1-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | product-common 13 | 14 | 15 | 16 | org.projectlombok 17 | lombok 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /product/common/src/main/java/com/geekerstar/product/common/ProductInfoOutput.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.common; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | * Created by 廖师兄 9 | * 2017-12-09 21:23 10 | */ 11 | @Data 12 | public class ProductInfoOutput { 13 | 14 | private String productId; 15 | 16 | /** 名字. */ 17 | private String productName; 18 | 19 | /** 单价. */ 20 | private BigDecimal productPrice; 21 | 22 | /** 库存. */ 23 | private Integer productStock; 24 | 25 | /** 描述. */ 26 | private String productDescription; 27 | 28 | /** 小图. */ 29 | private String productIcon; 30 | 31 | /** 状态, 0正常1下架. */ 32 | private Integer productStatus; 33 | 34 | /** 类目编号. */ 35 | private Integer categoryType; 36 | } 37 | -------------------------------------------------------------------------------- /product/server/src/test/java/com/geekerstar/product/service/CategoryServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.service; 2 | 3 | import com.geekerstar.product.ProductApplicationTests; 4 | import com.geekerstar.product.dataobject.ProductCategory; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by 廖师兄 15 | * 2017-12-09 22:07 16 | */ 17 | @Component 18 | public class CategoryServiceTest extends ProductApplicationTests { 19 | 20 | @Autowired 21 | private CategoryService categoryService; 22 | 23 | @Test 24 | public void findByCategoryTypeIn() throws Exception { 25 | List list = categoryService.findByCategoryTypeIn(Arrays.asList(11, 22)); 26 | Assert.assertTrue(list.size() > 0); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/dataobject/ProductInfo.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.dataobject; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import java.math.BigDecimal; 8 | import java.util.Date; 9 | 10 | /** 11 | * Created by 廖师兄 12 | * 2017-12-09 21:23 13 | */ 14 | @Data 15 | //@Table(name = "T_proxxx") 16 | @Entity 17 | public class ProductInfo { 18 | 19 | @Id 20 | private String productId; 21 | 22 | /** 名字. */ 23 | private String productName; 24 | 25 | /** 单价. */ 26 | private BigDecimal productPrice; 27 | 28 | /** 库存. */ 29 | private Integer productStock; 30 | 31 | /** 描述. */ 32 | private String productDescription; 33 | 34 | /** 小图. */ 35 | private String productIcon; 36 | 37 | /** 状态, 0正常1下架. */ 38 | private Integer productStatus; 39 | 40 | /** 类目编号. */ 41 | private Integer categoryType; 42 | 43 | private Date createTime; 44 | 45 | private Date updateTime; 46 | } 47 | -------------------------------------------------------------------------------- /product/server/src/test/java/com/geekerstar/product/repository/ProductCategoryRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.repository; 2 | 3 | import com.geekerstar.product.dataobject.ProductCategory; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by 廖师兄 16 | * 2017-12-09 21:43 17 | */ 18 | @RunWith(SpringRunner.class) 19 | @SpringBootTest 20 | public class ProductCategoryRepositoryTest { 21 | 22 | @Autowired 23 | private ProductCategoryRepository productCategoryRepository; 24 | 25 | @Test 26 | public void findByCategoryTypeIn() throws Exception { 27 | List list = productCategoryRepository.findByCategoryTypeIn(Arrays.asList(11, 22)); 28 | Assert.assertTrue(list.size() > 0); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /product/client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | product 7 | com.imooc 8 | 0.0.1-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | product-client 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-openfeign 18 | 19 | 20 | 21 | org.springframework 22 | spring-web 23 | 24 | 25 | 26 | com.imooc 27 | product-common 28 | 29 | 30 | -------------------------------------------------------------------------------- /product/server/src/test/java/com/geekerstar/product/repository/ProductInfoRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.repository; 2 | 3 | import com.geekerstar.product.dataobject.ProductInfo; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by 廖师兄 16 | * 2017-12-09 21:32 17 | */ 18 | @RunWith(SpringRunner.class) 19 | @SpringBootTest 20 | public class ProductInfoRepositoryTest { 21 | 22 | @Autowired 23 | private ProductInfoRepository productInfoRepository; 24 | 25 | @Test 26 | public void findByProductStatus() throws Exception { 27 | List list = productInfoRepository.findByProductStatus(0); 28 | Assert.assertTrue(list.size() > 0); 29 | } 30 | 31 | @Test 32 | public void findByProductIdIn() throws Exception { 33 | List list = productInfoRepository.findByProductIdIn(Arrays.asList("157875196366160022", "157875227953464068")); 34 | Assert.assertTrue(list.size() > 0); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /product/client/src/main/java/com/geekerstar/product/client/ProductClient.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.client; 2 | 3 | import com.geekerstar.product.common.DecreaseStockInput; 4 | import com.geekerstar.product.common.ProductInfoOutput; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | 10 | import java.util.List; 11 | 12 | //import org.springframework.cloud.netflix.feign.FeignClient; 13 | 14 | 15 | /** 16 | * Created by 廖师兄 17 | * 2017-12-10 21:04 18 | */ 19 | @FeignClient(name = "product", fallback = ProductClient.ProductClientFallback.class) 20 | public interface ProductClient { 21 | 22 | @PostMapping("/product/listForOrder") 23 | List listForOrder(@RequestBody List productIdList); 24 | 25 | @PostMapping("/product/decreaseStock") 26 | void decreaseStock(@RequestBody List decreaseStockInputList); 27 | 28 | @Component 29 | static class ProductClientFallback implements ProductClient { 30 | 31 | @Override 32 | public List listForOrder(List productIdList) { 33 | return null; 34 | } 35 | 36 | @Override 37 | public void decreaseStock(List decreaseStockInputList) { 38 | 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /product/server/src/test/java/com/geekerstar/product/service/ProductServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.service; 2 | 3 | import com.geekerstar.product.ProductApplicationTests; 4 | import com.geekerstar.product.common.DecreaseStockInput; 5 | import com.geekerstar.product.common.ProductInfoOutput; 6 | import com.geekerstar.product.dataobject.ProductInfo; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by 廖师兄 17 | * 2017-12-09 22:03 18 | */ 19 | @Component 20 | public class ProductServiceTest extends ProductApplicationTests{ 21 | 22 | @Autowired 23 | private ProductService productService; 24 | 25 | @Test 26 | public void findUpAll() throws Exception { 27 | List list = productService.findUpAll(); 28 | Assert.assertTrue(list.size() > 0); 29 | } 30 | 31 | @Test 32 | public void findList() throws Exception { 33 | List list = productService.findList(Arrays.asList("157875196366160022", "157875227953464068")); 34 | Assert.assertTrue(list.size() > 0); 35 | } 36 | 37 | @Test 38 | public void decreaseStock() throws Exception { 39 | DecreaseStockInput decreaseStockInput = new DecreaseStockInput("157875196366160022", 2); 40 | productService.decreaseStock(Arrays.asList(decreaseStockInput)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /product/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.geekerstar 7 | product 8 | 0.0.1-SNAPSHOT 9 | 10 | common 11 | server 12 | client 13 | 14 | pom 15 | 16 | product 17 | Demo project for Spring Boot 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-parent 22 | 2.0.2.RELEASE 23 | 24 | 25 | 26 | 27 | UTF-8 28 | UTF-8 29 | 1.8 30 | Finchley.RELEASE 31 | 0.0.1-SNAPSHOT 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-dependencies 39 | ${spring-cloud.version} 40 | pom 41 | import 42 | 43 | 44 | com.geekerstar 45 | product-common 46 | ${product-common.version} 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /eureka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.2.RELEASE 9 | 10 | 11 | com.geekerstar 12 | eureka 13 | 0.0.1-SNAPSHOT 14 | eureka 15 | eureka 16 | 17 | 18 | 1.8 19 | Greenwich.RELEASE 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-netflix-eureka-server 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-test 31 | test 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-dependencies 40 | ${spring-cloud.version} 41 | pom 42 | import 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | 57 | 58 | spring-milestones 59 | Spring Milestones 60 | https://repo.spring.io/milestone 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /product/server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | product 7 | com.imooc 8 | 0.0.1-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | product-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-test 28 | test 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | 37 | mysql 38 | mysql-connector-java 39 | 40 | 41 | 42 | org.projectlombok 43 | lombok 44 | 45 | 46 | 47 | com.imooc 48 | product-common 49 | 50 | 51 | 52 | org.springframework.cloud 53 | spring-cloud-config-client 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-amqp 59 | 60 | 61 | 62 | org.springframework.cloud 63 | spring-cloud-starter-sleuth 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-maven-plugin 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/controller/ProductController.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.controller; 2 | 3 | import com.geekerstar.product.VO.ProductInfoVO; 4 | import com.geekerstar.product.VO.ProductVO; 5 | import com.geekerstar.product.VO.ResultVO; 6 | import com.geekerstar.product.dataobject.ProductCategory; 7 | import com.geekerstar.product.dataobject.ProductInfo; 8 | import com.geekerstar.product.service.CategoryService; 9 | import com.geekerstar.product.utils.ResultVOUtil; 10 | import com.geekerstar.product.common.DecreaseStockInput; 11 | import com.geekerstar.product.common.ProductInfoOutput; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.stream.Collectors; 19 | 20 | /** 21 | * 商品 22 | * Created by 廖师兄 23 | * 2017-12-09 21:13 24 | */ 25 | @RestController 26 | @RequestMapping("/product") 27 | public class ProductController { 28 | 29 | @Autowired 30 | private ProductService productService; 31 | 32 | @Autowired 33 | private CategoryService categoryService; 34 | 35 | /** 36 | * 1. 查询所有在架的商品 37 | * 2. 获取类目type列表 38 | * 3. 查询类目 39 | * 4. 构造数据 40 | */ 41 | @GetMapping("/list") 42 | public ResultVO list() { 43 | //1. 查询所有在架的商品 44 | List productInfoList = productService.findUpAll(); 45 | 46 | //2. 获取类目type列表 47 | List categoryTypeList = productInfoList.stream() 48 | .map(ProductInfo::getCategoryType) 49 | .collect(Collectors.toList()); 50 | 51 | //3. 从数据库查询类目 52 | List categoryList = categoryService.findByCategoryTypeIn(categoryTypeList); 53 | 54 | //4. 构造数据 55 | List productVOList = new ArrayList<>(); 56 | for (ProductCategory productCategory: categoryList) { 57 | ProductVO productVO = new ProductVO(); 58 | productVO.setCategoryName(productCategory.getCategoryName()); 59 | productVO.setCategoryType(productCategory.getCategoryType()); 60 | 61 | List productInfoVOList = new ArrayList<>(); 62 | for (ProductInfo productInfo: productInfoList) { 63 | if (productInfo.getCategoryType().equals(productCategory.getCategoryType())) { 64 | ProductInfoVO productInfoVO = new ProductInfoVO(); 65 | BeanUtils.copyProperties(productInfo, productInfoVO); 66 | productInfoVOList.add(productInfoVO); 67 | } 68 | } 69 | productVO.setProductInfoVOList(productInfoVOList); 70 | productVOList.add(productVO); 71 | } 72 | 73 | return ResultVOUtil.success(productVOList); 74 | } 75 | 76 | /** 77 | * 获取商品列表(给订单服务用的) 78 | * 79 | * @param productIdList 80 | * @return 81 | */ 82 | @PostMapping("/listForOrder") 83 | public List listForOrder(@RequestBody List productIdList) { 84 | try { 85 | Thread.sleep(2000); 86 | } catch (InterruptedException e) { 87 | e.printStackTrace(); 88 | } 89 | return productService.findList(productIdList); 90 | } 91 | 92 | @PostMapping("/decreaseStock") 93 | public void decreaseStock(@RequestBody List decreaseStockInputList) { 94 | productService.decreaseStock(decreaseStockInputList); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /product/server/src/main/java/com/geekerstar/product/service/impl/ProductServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.geekerstar.product.service.impl; 2 | 3 | import com.geekerstar.product.common.DecreaseStockInput; 4 | import com.geekerstar.product.common.ProductInfoOutput; 5 | import com.geekerstar.product.enums.ProductStatusEnum; 6 | import com.geekerstar.product.enums.ResultEnum; 7 | import com.geekerstar.product.exception.ProductException; 8 | import com.geekerstar.product.utils.JsonUtil; 9 | import com.geekerstar.product.dataobject.ProductInfo; 10 | import com.geekerstar.product.repository.ProductInfoRepository; 11 | import org.springframework.amqp.core.AmqpTemplate; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | 16 | import javax.transaction.Transactional; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | import java.util.Optional; 20 | import java.util.stream.Collectors; 21 | 22 | /** 23 | * Created by 廖师兄 24 | * 2017-12-09 21:59 25 | */ 26 | @Service 27 | public class ProductServiceImpl implements ProductService { 28 | 29 | @Autowired 30 | private ProductInfoRepository productInfoRepository; 31 | 32 | @Autowired 33 | private AmqpTemplate amqpTemplate; 34 | 35 | @Override 36 | public List findUpAll() { 37 | return productInfoRepository.findByProductStatus(ProductStatusEnum.UP.getCode()); 38 | } 39 | 40 | @Override 41 | public List findList(List productIdList) { 42 | return productInfoRepository.findByProductIdIn(productIdList).stream() 43 | .map(e -> { 44 | ProductInfoOutput output = new ProductInfoOutput(); 45 | BeanUtils.copyProperties(e, output); 46 | return output; 47 | }) 48 | .collect(Collectors.toList()); 49 | } 50 | 51 | @Override 52 | public void decreaseStock(List decreaseStockInputList) { 53 | List productInfoList = decreaseStockProcess(decreaseStockInputList); 54 | 55 | //发送mq消息 56 | List productInfoOutputList = productInfoList.stream().map(e -> { 57 | ProductInfoOutput output = new ProductInfoOutput(); 58 | BeanUtils.copyProperties(e, output); 59 | return output; 60 | }).collect(Collectors.toList()); 61 | amqpTemplate.convertAndSend("productInfo", JsonUtil.toJson(productInfoOutputList)); 62 | 63 | } 64 | 65 | @Transactional 66 | public List decreaseStockProcess(List decreaseStockInputList) { 67 | List productInfoList = new ArrayList<>(); 68 | for (DecreaseStockInput decreaseStockInput: decreaseStockInputList) { 69 | Optional productInfoOptional = productInfoRepository.findById(decreaseStockInput.getProductId()); 70 | //判断商品是否存在 71 | if (!productInfoOptional.isPresent()){ 72 | throw new ProductException(ResultEnum.PRODUCT_NOT_EXIST); 73 | } 74 | 75 | ProductInfo productInfo = productInfoOptional.get(); 76 | //库存是否足够 77 | Integer result = productInfo.getProductStock() - decreaseStockInput.getProductQuantity(); 78 | if (result < 0) { 79 | throw new ProductException(ResultEnum.PRODUCT_STOCK_ERROR); 80 | } 81 | 82 | productInfo.setProductStock(result); 83 | productInfoRepository.save(productInfo); 84 | productInfoList.add(productInfo); 85 | } 86 | return productInfoList; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /eureka/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( 125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | echo Found %WRAPPER_JAR% 132 | ) else ( 133 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 134 | echo Downloading from: %DOWNLOAD_URL% 135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" 136 | echo Finished downloading %WRAPPER_JAR% 137 | ) 138 | @REM End of extension 139 | 140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 141 | if ERRORLEVEL 1 goto error 142 | goto end 143 | 144 | :error 145 | set ERROR_CODE=1 146 | 147 | :end 148 | @endlocal & set ERROR_CODE=%ERROR_CODE% 149 | 150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 154 | :skipRcPost 155 | 156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 158 | 159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 160 | 161 | exit /B %ERROR_CODE% 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 微服务 2 | 微服务是一种架构风格 3 | 4 | - 一系列微小的服务共同组成 5 | - 跑在自己的进程里 6 | - 每个服务为独立的业务开发 7 | - 独立部署 8 | - 分布式的管理 9 | 10 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/1.jpg) 11 | 12 | ## 点餐系统 13 | 设计的架构形态 14 | - 单体架构 15 | - 基于Ajax的前后端分离 16 | - 分布式(水平扩展 & 服务拆分) 17 | 18 | ## 单体架构 19 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/2.png) 20 | 21 | ### 单体架构优点 22 | - 容易测试 23 | - 容易部署 24 | 25 | ### 单体架构缺点 26 | - 开发效率低 27 | - 代码维护难 28 | - 部署不灵活 29 | - 稳定性不高 30 | - 扩展性不够 31 | 32 | ### 基于Ajax的前后端分离 33 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/3.png) 34 | 35 | ### 点餐服务的前后端分离 36 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/4.png) 37 | 38 | ### 分布式定义 39 | 40 | 旨在支持应用程序和服务的开发,可以利用物理架构由多个自治的处理元素,不共享主内存,但通过网络发送消息合作 41 | 42 | ### 简单的微服务架构 43 | 44 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/5.jpg) 45 | 46 | ### 微服务架构的基础框架/组件 47 | 48 | - 服务注册发现 49 | - 服务网关(Service Gateway) 50 | - 后端通用服务(也称中间层服务Middle Tier Service) 51 | - 前端服务(也称边缘服务Edge Service) 52 | 53 | ### SpringCloud Eureka 54 | 基于Netflix Eureka做了二次封装 55 | 56 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/7.png) 57 | 58 | 59 | 两个组件 60 | 61 | - Eureka Server 注册中心 62 | - Eureka Client 服务注册 63 | 64 | ### Eureka Server 高可用 65 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/6.png) 66 | 67 | ### Eureka总结 68 | - @EnableEurekaServer 69 | - @EnableEurekaClient 70 | - 心跳检测、健康检查、负载均衡等功能 71 | - Eureka高可用,生产上建议至少两台以上 72 | - 分布式系统中,服务注册中心是最重要的基础部分 73 | 74 | ## 分布式系统中为什么需要服务发现? 75 | 76 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/8.png) 77 | 78 | 79 | ### 服务发现的两种方式 80 | - 客户端发现(Eureka) 81 | - 服务端发现(Nginx、Zookeeper、Kubernetes) 82 | 83 | 84 | ### 微服务的特点:异构 85 | 86 | - 不同语言 87 | - 不同类型的数据库 88 | 89 | ### Springcloud的服务调用方式 90 | - REST 91 | - Node.js的eureka-js-client 92 | 93 | ## 服务拆分 - 起点和终点? 94 | 起点: 95 | 96 | - 既有架构的形态 97 | 98 | 终点: 99 | 100 | - 好的架构不是设计出来的,而是进化而来的 101 | - 一直在演进 102 | 103 | ### 适合上微服务吗? 104 | 业务形态不适合的 105 | - 系统中包含很多强事务场景的 106 | - 业务相对稳定,迭代周期长 107 | - 访问压力不大,可用性要求不高 108 | 109 | ### 康威定律 110 | 任何组织在设计一套系统(广义概念上的系统)时,所交付的设计方案在结构上都与该组织的沟通结构保持一致 111 | 112 | ### 微服务和团队结构 113 | 微服务的特点 114 | - 一系列微小的服务共同组成 115 | - 单独部署,跑在自己的进程里 116 | - 每个服务为独立的业务开发 117 | - 分布式的管理 118 | 119 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/9.jpg) 120 | 121 | ### 服务拆分的方法论 122 | 扩展立方模型(Scale Cube) 123 | - X轴 水平复制 124 | - Z轴 数据区分 125 | - Y轴 功能解耦 126 | 127 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/10.png) 128 | 129 | 如何拆"功能"? 130 | - 单一职责,松耦合,高内聚 131 | - 关注分离点(按职责、通用性、粒度级别) 132 | 133 | 服务和数据的关系: 134 | - 先考虑业务功能,再考虑数据 135 | - 无状态服务 136 | 137 | 如何拆"数据"? 138 | - 每个微服务都有单独的数据存储 139 | - 依据服务特点选择不同结构的数据库类型 140 | - 难点在确定边界(针对边界设计API、依据边界权衡数据冗余) 141 | 142 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/11.png) 143 | 144 | ### 点餐业务服务拆分分析 145 | 146 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/12.png) 147 | 148 | ## 应用间通信 149 | Springcloud中服务间两种RESTFul调用方式 150 | 151 | - RestTemplate 152 | 153 | - Feign 154 | 155 | ### RestTemplate 156 | 157 | 订单服务 -> 商品服务 158 | 159 | ### 客户端负载均衡 - Ribbon 160 | 161 | - RestTemplate 162 | 163 | - Feign 164 | 165 | - Zuul 166 | 167 | #### 特点 168 | 169 | - 服务发现 170 | 171 | - 服务选择规则 172 | 173 | - 服务监听 174 | 175 | #### 主要组件 176 | 177 | - ServerList 178 | 179 | - IRule 180 | 181 | - ServerListFilter 182 | 183 | ### Feign 184 | 185 | - 声明式REST客户端(伪RPC) 186 | 187 | - 采用了基于接口的注解 188 | 189 | ### 多模块划分 190 | 191 | - product-server:所有业务逻辑 192 | 193 | - product-client:对外暴露的接口 194 | 195 | - product-common:公用的对象 196 | 197 | #### 依赖关系 198 | 199 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/13.png) 200 | 201 | 202 | ### 同步 or 异步 203 | 204 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/14.png) 205 | 206 | ### 微服务和容器 - 天生一对 207 | 208 | - 从系统环境开始,自底至上打包应用 209 | - 轻量级,对资源的有效隔离和管理 210 | - 可复用,版本化 211 | 212 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/15.png) 213 | 214 | ## 统一配置中心 215 | 为什么需要统一配置中心? 216 | 217 | - 不方便维护 218 | - 配置内容安全与权限 219 | - 更新配置项目需要重启 220 | 221 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/16.png) 222 | 223 | ## 异步 224 | 客户端请求不会阻塞进程,服务端的响应可以是非即时的 225 | 226 | ### 异步的常见形态 227 | - 通知 228 | - 请求/异步响应 229 | - 消息 230 | 231 | ### MQ使用场景 232 | - 异步处理 233 | - 流量削峰 234 | - 日志处理 235 | - 应用解耦 236 | 237 | ## Spring cloud Stream 238 | 239 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/17.png) 240 | 241 | ## 原始流程 242 | - 1、查询商品信息(调用商品服务) 243 | - 2、计算总价(生成订单详情) 244 | - 3、商品服务扣库存(调用商品服务) 245 | - 4、订单入库(生成订单) 246 | 247 | ### 异步扣库存分析 248 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/18.png) 249 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/19.png) 250 | 251 | - 可靠的消息投递 252 | - 用户体验的变化 253 | 254 | ### 具体操作 255 | 256 | - 1、库存在Redis中保存 257 | - 2、收到请求Redis判断是否库存充足,减掉Redis中库存 258 | - 3、订单服务创建订单写入数据库,并发送消息 259 | 260 | ## 异步和消息处理 261 | - 数据一致性 262 | - Dubbo+Zookeeper和Springcloud 263 | 264 | ## 服务网关 265 | ### 为什么需要服务网关 266 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/20.png) 267 | 268 | ### 服务网关的要素 269 | - 稳定性和高可用 270 | - 性能和并发性 271 | - 安全性 272 | - 扩展性 273 | 274 | ### 常用的网关方案 275 | - Nginx+Lua 276 | - Kong 277 | - Tyk 278 | - Springcloud Zuul 279 | 280 | ### Zuul的特点 281 | - 路由+过滤器=Zuul 282 | - 核心是一系列的过滤器 283 | 284 | ### Zuul的四种过滤器API 285 | - 前置(Pre):限流、鉴权、参数校验调整 286 | - 后置(Post):统计、日志 287 | - 路由(Route) 288 | - 错误(Error) 289 | 290 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/21.jpg) 291 | 292 | ### 请求生命周期 293 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/22.jpg) 294 | 295 | ### Zuul的高可用 296 | - 多个Zuul节点注册到Eureka Server 297 | - Nginx和Zuul"混搭" 298 | 299 | ## Zuul综合使用 300 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/23.png) 301 | 302 | ### Zuul限流 303 | - 时机:请求被转发之前调用 304 | 305 | #### 令牌桶算法 306 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/24.jpg) 307 | 308 | ### Zuul权限校验 309 | - /order/create 只能买家访问 310 | - /order/finish 只能卖家访问 311 | - /product/list 都可以访问 312 | 313 | #### 解决方案 314 | - 在前置过滤器中实现相关逻辑 315 | - 分布式Session 或 OAuth2 316 | 317 | ### Zuul跨域问题 318 | - 在被调用的类或方法上加上@CrossOrigin注解 319 | - 在Zuul里增加CorsFilter过滤器 320 | 321 | ## Springcloud Hystrix 322 | 323 | - 防雪崩利器 324 | - 基于Netflix对应的Hystrix 325 | 326 | ### 功能 327 | #### 服务降级 328 | - 优先核心服务,非核心服务不可用或弱可用 329 | - 通过HystrixCommand注解指定 330 | - fallbackMethod(回退函数)中具体实现降级逻辑 331 | 332 | ### 依赖隔离 333 | - 线程池隔离 334 | - Hystrix自动实现了依赖隔离 335 | 336 | ### 服务熔断 337 | circuitBreaker.requestVolumeThreshold 338 | circuitBreaker.sleepWindowInMilliseconds 339 | circuitBreaker.errorThresholdPercentage 340 | 341 | - Circuit Breaker:断路器 342 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/25.jpg) 343 | 344 | ### 监控(Hystrix Dashboard) 345 | 346 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/26.jpg) 347 | 348 | ## 链路监控 349 | - SpringCloud Sleuth 350 | 351 | ### 集成步骤 352 | - 引入依赖 353 | - 启动 ZipKin Server 354 | - 配置参数 355 | 356 | ## 分布式追踪系统 357 | 核心步骤 358 | - 数据采集 359 | - 数据存储 360 | - 查询展示 361 | 362 | ### OpenTracing 363 | - 优势:来自大名鼎鼎的CNCF 364 | - ZIPKIN、TRACER、JAEGER、GRPC 365 | 366 | 367 | ### Annotation 368 | 事件类型: 369 | - cs(Client Send):客户端发起请求的时间 370 | - cr(client Received):客户端收到处理完请求的时间 371 | - ss(Server Send):服务端处理完逻辑的时间 372 | - sr(Server Received):服务端收到调用端请求的时间 373 | 374 | 客户端调用时间=cr-cs 375 | 376 | 服务端处理时间=sr-ss 377 | 378 | ### ZipKin 379 | ![](https://github.com/geekerstar/dive-in-springcloud/blob/master/img/27.jpg) 380 | 381 | 几个关键概念 382 | - traceId 383 | - spanId 384 | - parentId 385 | 386 | -------------------------------------------------------------------------------- /eureka/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | ########################################################################################## 204 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 205 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 206 | ########################################################################################## 207 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 208 | if [ "$MVNW_VERBOSE" = true ]; then 209 | echo "Found .mvn/wrapper/maven-wrapper.jar" 210 | fi 211 | else 212 | if [ "$MVNW_VERBOSE" = true ]; then 213 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 214 | fi 215 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" 216 | while IFS="=" read key value; do 217 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 218 | esac 219 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Downloading from: $jarUrl" 222 | fi 223 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 224 | 225 | if command -v wget > /dev/null; then 226 | if [ "$MVNW_VERBOSE" = true ]; then 227 | echo "Found wget ... using wget" 228 | fi 229 | wget "$jarUrl" -O "$wrapperJarPath" 230 | elif command -v curl > /dev/null; then 231 | if [ "$MVNW_VERBOSE" = true ]; then 232 | echo "Found curl ... using curl" 233 | fi 234 | curl -o "$wrapperJarPath" "$jarUrl" 235 | else 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Falling back to using Java to download" 238 | fi 239 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 240 | if [ -e "$javaClass" ]; then 241 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 242 | if [ "$MVNW_VERBOSE" = true ]; then 243 | echo " - Compiling MavenWrapperDownloader.java ..." 244 | fi 245 | # Compiling the Java class 246 | ("$JAVA_HOME/bin/javac" "$javaClass") 247 | fi 248 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 249 | # Running the downloader 250 | if [ "$MVNW_VERBOSE" = true ]; then 251 | echo " - Running MavenWrapperDownloader.java ..." 252 | fi 253 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 254 | fi 255 | fi 256 | fi 257 | fi 258 | ########################################################################################## 259 | # End of extension 260 | ########################################################################################## 261 | 262 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo $MAVEN_PROJECTBASEDIR 265 | fi 266 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 267 | 268 | # For Cygwin, switch paths to Windows format before running java 269 | if $cygwin; then 270 | [ -n "$M2_HOME" ] && 271 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 272 | [ -n "$JAVA_HOME" ] && 273 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 274 | [ -n "$CLASSPATH" ] && 275 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 276 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 277 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 278 | fi 279 | 280 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 281 | 282 | exec "$JAVACMD" \ 283 | $MAVEN_OPTS \ 284 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 285 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 286 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 287 | --------------------------------------------------------------------------------