首先pom.xml文件,spring boot、springcloud版本很麻煩,容易出問題
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xing</groupId> <artifactId>springboot-user</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>springboot-user</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR3</version><!--Edgware.SR4 Finchley.RELEASE --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- <dependencyManagement> --> <!-- <dependencies> --> <!-- <dependency> --> <!-- <groupId>org.springframework.cloud</groupId> --> <!-- <artifactId>spring-cloud-starter-parent</artifactId> --> <!-- <version>Edgware.SR2</version> --> <!-- <type>pom</type> --> <!-- <scope>import</scope> --> <!-- </dependency> --> <!-- </dependencies> --> <!-- </dependencyManagement> --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <!-- alibaba的druid數據庫連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> <!-- Swagger2的 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> <!--添加fastjson依賴--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.7</version> </dependency> <!-- 熱部署 --> <!-- <dependency> --> <!-- <groupId>org.springframework.boot</groupId> --> <!-- <artifactId>spring-boot-devtools</artifactId> --> <!-- <optional>true</optional> --> <!-- </dependency> --> <!-- eureka依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <!-- 用於注冊中心賬號登錄 --> <!-- <dependency> --> <!-- <groupId>org.springframework.boot</groupId> --> <!-- <artifactId>spring-boot-starter-security</artifactId> --> <!-- </dependency> --> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!-- 熱部署配置 --> <!-- <configuration> --> <!-- <fork>true</fork> --> <!-- </configuration> --> </plugin> <!-- mybatis generator 自動生成代碼插件 --> <!-- <plugin> --> <!-- <groupId>org.mybatis.generator</groupId> --> <!-- <artifactId>mybatis-generator-maven-plugin</artifactId> --> <!-- <version>1.3.2</version> --> <!-- <configuration> --> <!-- <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> --> <!-- <overwrite>true</overwrite> --> <!-- <verbose>true</verbose> --> <!-- </configuration> --> <!-- </plugin> --> </plugins> </build> <!-- 配置多個實例 --> <profiles> <profile> <id>first</id> <activation> <!-- 默認激活 --> <activeByDefault>true</activeByDefault> </activation> <properties> <spring.profiles.active>first</spring.profiles.active> </properties> </profile> <profile> <id>second</id> <properties> <spring.profiles.active>second</spring.profiles.active> </properties> </profile> </profiles> </project>
此處為了實現負載均衡,所以采用多實例運行在不同端口模擬集群的方式。所以配置多個yml文件(eclipse需配置多個yml,IDEA不需要,IDEA可以動態傳入參數,多端口啟動)
application.yml如下:
spring:
profiles:
active: first
application-first.yml如下:
server: port: 8070 spring: application: name: xing-user #指定服務名 datasource: name: test type: com.alibaba.druid.pool.DruidDataSource #druid相關配置 druid: #監控統計攔截的filters filters: stat driver-class-name: com.mysql.jdbc.Driver #基本屬性 url: jdbc:mysql://192.168.***.***:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true username: root password: root #配置初始化大小/最小/最大 initial-size: 1 min-idle: 1 max-active: 20 #獲取連接等待超時時間 max-wait: 60000 #間隔多久進行一次檢測,檢測需要關閉的空閑連接 time-between-eviction-runs-millis: 60000 #一個連接在池中最小生存的時間 min-evictable-idle-time-millis: 300000 validation-query: SELECT 'x' test-while-idle: true test-on-borrow: false test-on-return: false #打開PSCache,並指定每個連接上PSCache的大小。oracle設為true,mysql設為false。分庫分表較多推薦設置為false pool-prepared-statements: false max-pool-prepared-statement-per-connection-size: 20 eureka: client: registerWithEureka: true #是否將自己注冊到Eureka服務中,默認為true fetchRegistry: true #是否從Eureka中獲取注冊信息,默認為true serviceUrl: #Eureka客戶端與Eureka服務端進行交互的地址 defaultZone: http://xing-eurekaServer:8090/eureka/ eurekaServerConnectTimeoutSeconds: 60 eurekaServerReadTimeoutSeconds: 60 instance: prefer-ip-address: true #將自己的ip地址注冊到Eureka服務中 ip-address: 127.0.0.1 instance-id: xing-user:8070 #指定實例id lease-expiration-duration-in-seconds: 30 #續約更新時間間隔(默認30秒) lease-renewal-interval-in-seconds: 10 # 續約到期時間(默認90秒) leaseRenewalIntervalInSeconds: 10 #心跳時間 hostname: xing-user ## 該配置節點為獨立的節點,有很多同學容易將這個配置放在spring的節點下,導致配置無法被識別 #mybatis: # mapper-locations: classpath:mapper/*.xml #注意:一定要對應mapper映射xml文件的所在路徑 # type-aliases-package: com.winterchen.model # 注意:對應實體類的路徑 #pagehelper pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql returnPageInfo: check
application-second.yml 如下:
server: port: 8071 spring: application: name: xing-user #指定服務名 datasource: name: test type: com.alibaba.druid.pool.DruidDataSource #druid相關配置 druid: #監控統計攔截的filters filters: stat driver-class-name: com.mysql.jdbc.Driver #基本屬性 url: jdbc:mysql://192.168.254.128:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true username: root password: root #配置初始化大小/最小/最大 initial-size: 1 min-idle: 1 max-active: 20 #獲取連接等待超時時間 max-wait: 60000 #間隔多久進行一次檢測,檢測需要關閉的空閑連接 time-between-eviction-runs-millis: 60000 #一個連接在池中最小生存的時間 min-evictable-idle-time-millis: 300000 validation-query: SELECT 'x' test-while-idle: true test-on-borrow: false test-on-return: false #打開PSCache,並指定每個連接上PSCache的大小。oracle設為true,mysql設為false。分庫分表較多推薦設置為false pool-prepared-statements: false max-pool-prepared-statement-per-connection-size: 20 eureka: client: registerWithEureka: true #是否將自己注冊到Eureka服務中,默認為true fetchRegistry: true #是否從Eureka中獲取注冊信息,默認為true serviceUrl: #Eureka客戶端與Eureka服務端進行交互的地址 defaultZone: http://xing-eurekaServer:8091/eureka/ eurekaServerConnectTimeoutSeconds: 60 eurekaServerReadTimeoutSeconds: 60 instance: prefer-ip-address: true #將自己的ip地址注冊到Eureka服務中 ip-address: 127.0.0.1 instance-id: xing-user:8071 #指定實例id lease-expiration-duration-in-seconds: 30 #續約更新時間間隔(默認30秒) lease-renewal-interval-in-seconds: 10 # 續約到期時間(默認90秒) leaseRenewalIntervalInSeconds: 10 #心跳時間 hostname: xing-user ## 該配置節點為獨立的節點,有很多同學容易將這個配置放在spring的節點下,導致配置無法被識別 #mybatis: # mapper-locations: classpath:mapper/*.xml #注意:一定要對應mapper映射xml文件的所在路徑 # type-aliases-package: com.winterchen.model # 注意:對應實體類的路徑 #pagehelper pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql returnPageInfo: check
先整體看一下項目結構:

先創建一個實體類user.java:
U
package com.xing.user.entity; import java.io.Serializable; public class User implements Serializable{ // @Fields serialVersionUID : TODO private static final long serialVersionUID = 1L; private int id; private String name; private String nameEn; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNameEn() { return nameEn; } public void setNameEn(String nameEn) { this.nameEn = nameEn; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", nameEn=" + nameEn + ", age=" + age + "]"; } public User(String name, String nameEn, int age) { super(); this.name = name; this.nameEn = nameEn; this.age = age; } public User() { super(); } }
創建mapper,我這里直接使用注解方式,沒有使用xml方式
package com.xing.user.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import com.xing.user.entity.User; @Mapper public interface UserMapper { //這里的表名區分大小寫 @Select("SELECT * FROM user WHERE NAME = #{name}") User selectByName(@Param("name") String name); @Insert("insert into user (name,nameEn,age) value (#{name},#{nameEn},#{age})") int insertUser(@Param("name") String name ,@Param("nameEn") String nameEn ,@Param("age") int age); }
創建service
package com.xing.user.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.xing.user.dao.UserMapper; import com.xing.user.entity.User; @Service public class UserService { @Autowired private UserMapper userMapper; @Transactional public User findByName(String name) { return userMapper.selectByName(name); } }
創建controller
package com.xing.user.contorller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.http.MediaType; import com.xing.user.entity.User; import com.xing.user.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; @RestController @Api(tags="用戶接口", produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @ApiOperation(value = "查詢用戶", notes = "查詢用戶")//方法說明 // @ApiResponses({ @ApiResponse(code = CommonStatus.OK, message = "操作成功"), // @ApiResponse(code = CommonStatus.EXCEPTION, message = "服務器內部異常"), // @ApiResponse(code = CommonStatus.FORBIDDEN, message = "權限不足") }) @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = User.class)})//響應數據說明,可以有多個 @ApiImplicitParam(name = "name", value = "用戶名", paramType = "path", required = true, dataType = "String") //produces = { "application/json;charset=UTF-8" } 這段代碼是因為集成了EurekaServer,又需要jackson-dataformat-xml這個依賴,如果不設置這段代碼,會返回xml格式,而不是json @GetMapping(value = "/findByName/{name}",produces = { "application/json;charset=UTF-8" }) public User findByName(@PathVariable String name) { System.out.println("----------------------------"+name); return userService.findByName(name); } }
增加SwaggerConfig,使用 swagger2管理RestFul API配置swagger2
package com.xing.user.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.async.DeferredResult; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import io.swagger.annotations.ApiOperation; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** */ @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enableUrlTemplating(true) .select() // 掃描所有有注解的api,用這種方式更靈活 .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("webapp接口文檔") .description("章建星test接口,簡單接口服務管理!") .termsOfServiceUrl("https://www.baidu.com") .contact(new Contact("struggling_rong", "https://www.baidu.com", "1743719440@qq.com")) .version("1.0.0") .build(); } }
配置好swagger可以看到swagger2的頁面如下:

去eureka界面查看服務已經注冊成功


服務也能正常工作,致此,簡單的一個一個服務注冊和管理就完成了
源碼地址:https://github.com/OnlyXingxing/SpringCloud
