IDE开发工具:IntelliJ IDEA 14.0.2
版本管理:Maven
技术栈:SpringCloud
环境:JDK 1.8
1、File——>New Project ——>Maven 如图所示:
2、填写模块名称和项目路径
按照以上步骤,就简单的创建了一个Maven项目。
此时项目还不是SpringBoot项目
按同样方法创建子项目,注意组名后面需要在pom中声明。一个最简单的微服务项目结构如下。其中common为实体等单独抽离,其他项目将其作为以来引入的模块。eureka-server为eureka服务端,其他业务模块要作为客户端进行注册。system-management为一个业务模块的样例,其中实现了一个登录接口。
1、总项目
主要管理各模块和依赖的版本
groupId要改为自己创建项目时的groupId
4.0.0
com.cloud
cloud-demo
1.0-SNAPSHOT
eureka
web-server
common
system-management
pom
org.springframework.boot
spring-boot-starter-parent
1.5.22.RELEASE
8
8
com.spotify
docker-maven-plugin
0.4.3
true
2.common模块
需要指定parent为总项目的artifactId
groupId要改为自己创建项目时的groupId
cloud-demo
com.cloud
1.0-SNAPSHOT
4.0.0
common
8
8
org.projectlombok
lombok
true
3.eureka-server
工件和组名同理
核心依赖是
eureka-server
其他依赖根据代码需要引入
cloud-demo
com.cloud
1.0-SNAPSHOT
4.0.0
eureka
UTF-8
UTF-8
1.8
Edgware.SR6
org.springframework.cloud
spring-cloud-starter-eureka-server
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
4.微服务模块
工件和组名同理
核心依赖是eureka客户端、Feign客户端、Springboot
和公共模块
4.0.0
cloud-demo
com.cloud
1.0-SNAPSHOT
system-management
system-management
UTF-8
UTF-8
1.8
Edgware.SR6
org.springframework.cloud
spring-cloud-starter-eureka
org.mybatis
mybatis
3.4.6
compile
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.4
mysql
mysql-connector-java
5.1.35
log4j
log4j
1.2.17
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-feign
com.cloud
common
1.0-SNAPSHOT
compile
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
5.Feign
核心依赖是
Eureka客户端、Feign服务端、Springboot、公共模块
cloud-demo
com.cloud
1.0-SNAPSHOT
4.0.0
web-server
jar
UTF-8
UTF-8
1.8
Edgware.SR6
org.springframework.cloud
spring-cloud-starter-feign
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
com.cloud
common
1.0-SNAPSHOT
compile
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
1.eureka-server
主要作用是配置端口号
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#设置与eureka server交互的地址和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka/ #单机就是指向自己
2.微服务模块
主要作用是配置端口号和mybatis和数据库
server.port=8099
#server.servlet.context-path=/disk
#spring.web.resources.static-locations=classpath:/templates/, classpath:/static/
spring.application.name=system-management
# MyBatis Configuration
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
mybatis.type-aliases-package=import com.cloud.pojo
# Database Configuration
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
3.Feign
配置端口号即可
各配置文件位置如下
其中system-management是一个微服务模块,web-server为Feign
yml在各模块resources目录下,pom在各模块根目录下
各依赖和配置项最好能了解理解其作用,如果出现问题有助于解决。
版本最好统一管理。
1.eureka启动器
package com.buba.springcloud.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain {
public static void main(String[] args) {
SpringApplication.run(EurekaMain.class,args);
}
}
2.微服务启动器
package com.study.springcloud.systemmanagement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class SystemManagementApplication {
public static void main(String[] args) {
SpringApplication.run(SystemManagementApplication.class, args);
}
}
3.Feign启动器
package com.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
//@ComponentScan(basePackages = {"com.study.springcloud.feign"})
//@EnableDiscoveryClient
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
//@EnableFeignClients(basePackages = "com.cloud.client")
//@EnableFeignClients(basePackages = {"com.cloud"})
public class WebServerApplication {
public static void main(String[] args) {
SpringApplication.run(WebServerApplication.class, args);
}
}
4.公共类
package com.cloud.pojo;
public class User {
private int id;
private String username;
private String password;
public User() {
}
public User(String username, String password){
this.username=username;
this.password=password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
5.Feign
5.1FeignClient
package com.cloud.client;
import com.cloud.pojo.User;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name="system-management",url = "http://localhost:8099")
public interface LoginClient {
@RequestMapping(value = "/login",method = RequestMethod.GET)
boolean Login(@RequestParam("username") String username, @RequestParam("password") String password);
}
5.2 Controller
package com.cloud.controller;
import com.cloud.pojo.User;
import com.cloud.client.LoginClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/webs")
public class LoginController {
@Autowired
private LoginClient loginClient;
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String Login(HttpServletRequest request){
//System.out.println("ok");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("请求中username=:"+username);
User user=new User(username,password);
System.out.println("读取请求参数构造的user对象:"+user);
System.out.println("读取请求参数构造的user对象的username:"+user.getUsername());
if(loginClient.Login(user.getUsername(),user.getPassword())){
return "success";
}
return "failed";
}
}
6.微服务
6.1Controller
package com.study.springcloud.systemmanagement.controller;
import com.cloud.pojo.User;
import com.study.springcloud.systemmanagement.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping
public class LoginController {
@Autowired
private LoginService loginService;
//@RequestMapping(value = "/login", method = RequestMethod.GET)
@RequestMapping(value = "/login",method = RequestMethod.GET)
@ResponseBody
public boolean login(String username,String password) {
// System.out.println("传给微服务的user:"+user);
// System.out.println("传给微服务的user的username:"+user.getUsername());
System.out.println("传给微服务的username:"+username);
User user_result = this.loginService.login(username, password);
//System.out.println(user_result);
return user_result != null;
}
}
6.2Service
package com.study.springcloud.systemmanagement.service;
import com.cloud.pojo.User;
public interface LoginService {
User login(String username, String password);
}
6.3Service实例化
package com.study.springcloud.systemmanagement.controller;
import com.cloud.pojo.User;
import com.study.springcloud.systemmanagement.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping
public class LoginController {
@Autowired
private LoginService loginService;
//@RequestMapping(value = "/login", method = RequestMethod.GET)
@RequestMapping(value = "/login",method = RequestMethod.GET)
@ResponseBody
public boolean login(String username,String password) {
// System.out.println("传给微服务的user:"+user);
// System.out.println("传给微服务的user的username:"+user.getUsername());
System.out.println("传给微服务的username:"+username);
User user_result = this.loginService.login(username, password);
//System.out.println(user_result);
return user_result != null;
}
}
6.4Dao
package com.study.springcloud.systemmanagement.dao;
import com.cloud.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserDao {
User login(@Param("username") String username, @Param("password") String password);
}
6.5 mapper.XML
三个服务均能启动
通过postman测试
控制台打印的信息也正常
最好初步理解springboot、springcloud架构,以及各组件功能,了解常见依赖后再尝试搭建。
以下为作者个人理解,敬请指正。
搭建时注意各配置文件参数改成自己的。
版本最好使用管理工具统一版本,避免因此出错。
要有耐心,完事开头难。
作者搭建时遇到过诸多错误,都是一步一步解决的。
譬如mapper.xml配置dao路径错误(不会报错,难以发现);
EnableFeignClients注解无法扫描到FeignClient,原因是版本不兼容,项目整体重构、各模块统一版本后才得以解决(Springboot和Springcloud组件也有兼容性问题);
Feign传参给微服务时传不过去值,原因是FeignClient的method参数缺省,底层原理还尚未知晓。