业务界定:以生产者消费者为例,服务端生产者,客户端消费者,对外提供的服务
本章以maven聚合工程为例
步骤一:创建parent工程 名为springCloud 依赖注意是pom类型
<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.gcxzflgl.spring</groupId>
<artifactId>springCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>springCloud-api</module>
<module>springCloud-provider-dept</module>
<module>springCloud-cousumer-dept</module>
</modules>
</project>
步骤二:创建公共模块,我们把多次调用的类或者模块抽象出单独的模块供其他模块引用,名为springCloud-api,要引入父工程
<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>
<parent>
<groupId>com.gcxzflgl.spring</groupId>
<artifactId>springCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springCloud-api</artifactId>
<dependencies><!-- 当前Module需要用到的jar包,按自己需求添加,如果父类已经包含了,可以不用写版本号 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
</project>
并且创建公共类实体Dept,也可以再这个公共类中引入lombok插件依赖,就不用在麻烦生成对应set/get代码,编写好后mvn打包到本地供其他模块引用,工程->run as->mvn install
步骤三:创建数据库脚本
DROP DATABASE IF EXITS db_springcloud;
create database db_springcloud CHARACTER set UTF8;
use db_springcloud;
create table dept(
deptno BIGINT not null PRIMARY key auto_increment,
dname varchar(60),
db_source varchar(60)
);
insert into dept(dname,db_source) values('开发部',DATABASE());
insert into dept(dname,db_source) values('人事部',DATABASE());
insert into dept(dname,db_source) values('财务部',DATABASE());
insert into dept(dname,db_source) values('市场部',DATABASE());
insert into dept(dname,db_source) values('运维部',DATABASE());
步骤四:构建生产者对外提供服务,访问端口用8001
按照开发流程,约定>配置>编码
创建工程springCloud-provide-dept,依赖于springCloud-api
<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>
<parent>
<groupId>com.gcxzflgl.spring</groupId>
<artifactId>springCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springCloud-provider-dept</artifactId>
<dependencies>
<!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
<dependency>
<groupId>com.gcxzflgl.spring</groupId>
<artifactId>springCloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
在resources下添加mysql驱动配置文件application.yml 访问端口8001
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.gcxzflgl.springCloud.entity # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservicecloud-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/db_springCloud # 数据库名称
username: root
password: 123456
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
并且在resources下创建mybatis文件夹,用于存放mybatis.cfg.xml,mybatis文件夹下创建mapper用于存放映射关系
首先配置mybatis.cfg.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" /><!-- 二级缓存开启 -->
</settings>
</configuration>
其次是我们很熟悉很传统的 dao,Service,controller
Dao层接口,注意@Mapper注解别丢掉
package com.gcxzflgl.springCloud.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.gcxzflgl.springCloud.entity.Dept;
@Mapper
public interface DeptDao {
public boolean addDept(Dept dept);
public Dept findById(Long id);
public List<Dept> findAll();
}
映射文件xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gcxzflgl.springCloud.dao.DeptDao">
<select id="findById" resultType="Dept" parameterType="Long">
select deptno,dname,db_source from dept where deptno=#{deptno};
</select>
<select id="findAll" resultType="Dept">
select deptno,dname,db_source from dept;
</select>
<insert id="addDept" parameterType="Dept">
INSERT INTO dept(dname,db_source) VALUES(#{dname},DATABASE());
</insert>
</mapper>
Service层
package com.gcxzflgl.springCloud.service;
import java.util.List;
import com.gcxzflgl.springCloud.entity.Dept;
public interface DeptService{
public boolean add(Dept dept);
public Dept get(Long id);
public List<Dept> list();
}
package com.gcxzflgl.springCloud.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gcxzflgl.springCloud.dao.DeptDao;
import com.gcxzflgl.springCloud.entity.Dept;
import com.gcxzflgl.springCloud.service.DeptService;
@Service
public class DeptServiceImpl implements DeptService{
@Autowired
private DeptDao dao;
@Override
public boolean add(Dept dept)
{
return dao.addDept(dept);
}
@Override
public Dept get(Long id)
{
return dao.findById(id);
}
@Override
public List<Dept> list()
{
return dao.findAll();
}
}
Controller层,采用Rest方式对外提供服务
package com.gcxzflgl.springCloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;
import com.gcxzflgl.springCloud.entity.Dept;
import com.gcxzflgl.springCloud.service.DeptService;
@RestController
public class DeptController{
@Autowired
private DeptService service;
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(@RequestBody Dept dept){
return service.add(dept);
}
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") Long id){
return service.get(id);
}
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list(){
return service.list();
}
}
编写主类运行测试:
package com.gcxzflgl.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DeptProvider8001_App{
public static void main(String[] args){
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
出现以上结果代表提供者服务正常
步骤五:编写消费者 名称 springCloud-consumer-dept
<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>
<parent>
<groupId>com.gcxzflgl.spring</groupId>
<artifactId>springCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springCloud-cousumer-dept</artifactId>
<dependencies>
<dependency><!-- 自己定义的api -->
<groupId>com.gcxzflgl.spring</groupId>
<artifactId>springCloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
在resources下添加application.yml配置文件
server:
port: 80
Springcloud中的服务消费,就需要我们服务之前相互发请求了。之前我们都是想着用http请求相关的交互,用的比较多的是 apache httpcomponents ,现在springboot提供了RestTemplate更高级别的方法来满足我们的功能.
创建一个配置类
package com.gcxzflgl.springCloud.confBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
编写Controller层,直接用restTemplate进行交互
RestTemplate官网地址:
RestTemplate官网地址
package com.gcxzflgl.springCloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.gcxzflgl.springCloud.entity.Dept;
@RestController
public class DeptController_Consumer
{
private static final String REST_URL_PREFIX = "http://localhost:8001";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/dept/add")
public boolean add(Dept dept){
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
@RequestMapping(value = "/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id)
{
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
@SuppressWarnings("unchecked")
@RequestMapping(value = "/consumer/dept/list")
public List<Dept> list()
{
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}
}
编写主类测试最终结果:
package com.gcxzflgl.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DeptConsumer80_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptConsumer80_App.class, args);
}
}
我们看到最终结果,消费者进行消费,暴露给消费者的80,实际起作用的8001,从而达到对外提供服务,微服务代表服务大小,只提供对应的功能,一个服务是一个线程。我们看到有两个线程在运行中