微服务学习1——微服务环境搭建

微服务学习1——微服务环境搭建

(参考黑马程序员项目)
个人仓库地址:https://gitee.com/jkangle/springboot-exercise.git

微服务就是将单体应用进一步拆分,拆成更小的服务,拆完之后怎么调用,主流的技术有RESTful和RPC,(首先以RESTful为例子)

1.模块设计

shop-common 公共模块——相当于工具类

shop-user 用户微服务——存储用户的信息

shop-product 商品微服务——存储商品的所有信息

shop-order 订单微服务——存储订单的所有信息

【注意】所有的对数据库的操作是结合JPA

2.实现目标

通过订单微服务来查询商品的信息,也就是通过订单的微服务调用商品的微服务

微服务学习1——微服务环境搭建_第1张图片

3.具体实现

微服务学习1——微服务环境搭建_第2张图片

3.1创建一个父工程test

父工程做的内容就是规定好这个项目所有的版本号这些,因此只需要pom.xml文件即可


<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.0modelVersion>

    <groupId>org.examplegroupId>
    <artifactId>testartifactId>
    <version>1.0-SNAPSHOTversion>


    <packaging>pompackaging>
    <modules>
        <module>shop-commonmodule>
        <module>shop-usersmodule>
        <module>shop-productmodule>
        <module>shop-ordermodule>
    modules>

    <properties>
        <maven.compiler.source>1.8maven.compiler.source>
        <maven.compiler.target>1.8maven.compiler.target>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>

        <spring-boot.version>2.7.3spring-boot.version>
        <spring-cloud.version>2021.0.7spring-cloud.version>
        <spring-cloud-alibaba.version>2.1.0.RELEASEspring-cloud-alibaba.version>
        <fastjson.version>1.2.57fastjson.version>
    properties>

    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-dependenciesartifactId>
                <version>${spring-boot.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>

            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>

            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>${spring-cloud-alibaba.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>

            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>fastjsonartifactId>
                <version>${fastjson.version}version>
            dependency>

        dependencies>
    dependencyManagement>

project>
3.2在父工程中创建公共模块

公共模块就是相当于是一个工具类,里面有数据库信息的实体类

package pojo;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * 订单的实体类
 */
@Entity(name = "shop_order")
@Data
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    /**
     * 订单id
     */
    private int oid;
    /**
     * 用户id
     */
    private Integer uid;
    /**
     * 物品id
     */
    private Integer pid;
    /**
     * 物品名称
     */
    private String pname;
    /**
     * 物品价格
     */
    private Double pprice;
    /**
     * 用户姓名
     */
    private String username;
    /**
     * 购买数量
     */
    private Integer number;
}

package pojo;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 *
 *
 * @author jkk
 * @since 2020-03-20-20:25
 */
@Entity(name = "shop_product")
@Data
public class Product {

    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer pid;

    /**
     * 商品名称
     */
    private String pname;

    /**
     * 商品价格
     */
    private double pprice;

    /**
     * 库存
     */
    private Integer stock;

}

3.3在父工程中创建用户模块

用户模块就是实现与用户的表相关的操作,对用户的业务就放到这个模块中,所以每一个模块中必须有一个启动类Application,当然需要配置它的yml文件

package org.example.users;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @author jkk
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ShopUsersApplications {
    public static void main(String[] args) {
        SpringApplication.run(ShopUsersApplications.class, args);
    }
}

server:
  port: 8071
spring:
  application:
    name: service-product
  datasource:
    url: jdbc:mysql://localhost:3306/shop?characterEncoding=UTF-8
    username: root
    password:
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

当前微服务并没有使用,所以没有写相关的具体业务


3.4在父工程中创建商品模块

同理将商品所需要的业务写在里面

controller

package org.example.product.controller;

import com.alibaba.fastjson.JSON;
import org.example.product.service.ProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;
import pojo.Product;

@RestController
public class ProductController {

    private static final Logger log = LoggerFactory.getLogger(ProductController.class);

    @Autowired
    private ProductService productService;

    @GetMapping("/product/{pid}")
    public Product product(@PathVariable("pid") Integer pid) {
        Product product = productService.findByPid(pid);
        log.info("查询到商品:" + JSON.toJSONString(product));
        return product;
    }
}

dao

package org.example.product.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import pojo.Product;

@Repository
public interface ProductDao extends JpaRepository<Product,Integer> {


}

service

package org.example.product.service;

import pojo.Product;

public interface ProductService {
     Product findByPid(Integer pid);
}

package org.example.product.service.impl;

import org.example.product.dao.ProductDao;
import org.example.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pojo.Product;

import java.util.Optional;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductDao productDao;

    @Override
    public Product findByPid(Integer pid) {
        Optional<Product> optional = productDao.findById(pid);
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }

}

启动类

package org.example.product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
@SpringBootApplication
@EntityScan(basePackages = "pojo")
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class,args);
    }
}

配置文件

server:
  port: 8081

spring:
  application:
    name: service-product
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?characterEncoding=UTF-8
    username: root
    password:
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect


3.5在父工程中创建订单模块

controller

package org.example.controller;

import com.alibaba.fastjson.JSON;
import org.example.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.RestController;
import org.springframework.web.client.RestTemplate;
import pojo.Order;
import pojo.Product;

/**
 * 使用restTemplate对象调用shop-product的请求方法
 */
@RestController
public class OrderController {
    private static final Logger log = LoggerFactory.getLogger(OrderController.class);
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderService orderService;

    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid){
        Product product = restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class);
        log.info(">>商品信息,查询结果:" + JSON.toJSONString(product));
        Order order = new Order();
        order.setOid(1);
        order.setUid(1);
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        orderService.save(order);
        return order;
    }

}

dao

package org.example.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import pojo.Order;
@Repository
public interface OrderDao extends JpaRepository<Order,Integer> {
}

service

package org.example.service;

import pojo.Order;

/**
 * 订单的service层接口
 */
public interface OrderService {
    /**
     * 将订单存到数据库
     * @param order
     */
    public void save(Order order);
}

package org.example.service.impl;

import org.example.dao.OrderDao;
import org.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pojo.Order;

/**
 * service接口的实现
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;

    /**
     * 存储订单
     * @param order
     */
    @Override
    public void save(Order order) {
        orderDao.save(order);
    }
}

启动类

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.client.RestTemplate;

/**
 * shop-order的启动类
 * @author jkk
 */
@SpringBootApplication
@EnableJpaRepositories
@EntityScan(basePackages = "pojo")
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

yml配置文件

server:
  port: 8091

spring:
  application:
    name: service-product
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?characterEncoding=UTF-8
    username: root
    password:

  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

4.运行

可以注意到,当前调用另一个微服务的时候是通过把服务提供者的网络地址 (ip,端口)等硬编码到了代码中

在这里插入图片描述

你可能感兴趣的:(Java学习笔记,微服务,学习,架构)