JAVA服务器开发

分布式系统开发---订单服务分离SpringCloud(四)

2019-01-03  本文已影响35人  Felix_

订单服务的分离其实跟商品服务的分离差不多,但是为什么要进行单独的分析呢?因为之前在同一个服务器中,订单服务商品服务都是可以接触到本服务器的数据的,但是,分离之后,商品服务中的商品信息数据将不再能被订单服务直接获取到,所以,当用户请求订单信息的时候,订单服务要自己先去商品服务中请求商品信息,然后把订单信息拼接上商品信息一并返回给用户。

好了,有了思路,那么下面我们按照这个思路对我们的项目进行改造。

首先,与商品服务分离类似,我们把mall/src/main/java/com/felix中的三个包拷贝粘贴到order模块下的felix包内,然后把三个包内和订单无关的内容全部删除(注意,这里不要删除Goods模型,因为从商品服务中请求回来的商品信息最终还要使用Goods模型进行包装),最终只保留GoodsOrderOrderDetailsOrderServiceGoodsServiceOrderController,如图所示


接下来,我们模拟这种情况,在订单服务中,是没有商品信息的,所以,我们的GoodsService中就不能也不允许有商品的数据了,所以,我们改造GoodsService成如下代码
package com.felix.service;

import com.felix.model.Goods;
import org.springframework.stereotype.Service;

/**
 * Created by weistekweistek on 2019/1/3.
 */
@Service
public class GoodsService {
    public Goods findGoodsById(Long id){
        return null;
    }
}

这里的返回值我们暂时写成空值,后面我们再修改它为从商品服务的服务器中获取商品信息并返回。
既然GoodsService中已经没有了商品信息,那么响应的OrderService中在初始化构造的假数据就不能再次使用了,我们直接在假数据中新建一个没有意义的商品数据(可以设置商品id,因为正常业务中订单信息中本身就可保存了商品id,只是没有商品的详细信息)。

package com.felix.service;

import com.felix.model.Goods;
import com.felix.model.Order;
import com.felix.model.OrderDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by weistekweistek on 2019/1/3.
 */
@Service
public class OrderService {
    @Autowired
    private GoodsService goodsService;
    private static final Map<Long,Order> order_map = new HashMap<Long,Order>();
    static {
        List<OrderDetails> orderDetailsList = new ArrayList<OrderDetails>();
        for (Long i = 1L;i <= 10L;i++){
            Goods goods = new Goods();
            goods.setGoodsid(i);
            orderDetailsList.add(new OrderDetails(i ,i,goods,5));
            order_map.put(i,new Order(i,i,new Date(),new Date(),new ArrayList<OrderDetails>(orderDetailsList)));
            System.out.println(order_map);
        }
    }
    public Order findOrderById(Long id){
        Order order = order_map.get(id);
        for (OrderDetails orderDetails : order.getOrderDetailsList()){
            Goods goods = goodsService.findGoodsById(orderDetails.getGoods().getGoodsid());
            orderDetails.setGoods(goods);
        }
        return order;
    }
}

上面代码中我们直接做了假的订单信息,并且添加了响应的商品id进去,也就是模拟了正常的订单信息,那么,GoodsDetails中的goods现在只有id,并没有其他的信息,如何使用id获取商品服务服务器上面的商品信息呢?还记得刚才改造的GoodsService吗,它可以帮助我们去获取商品信息,至于怎么获取,那是它的事情,我们只需要在OrderService中使用GoodsService去写就行了,所以,在查询订单的时候,我们先查看订单中有多少商品,然后使用商品id去查找商品就行了(记得要注入GoodsService),也就是上面的

 for (OrderDetails orderDetails : order.getOrderDetailsList()){
            Goods goods = goodsService.findGoodsById(orderDetails.getGoods().getGoodsid());
            orderDetails.setGoods(goods);
}

现在回到了订单服务需要从商品服务中获取商品信息的阶段,怎么实现呢,我们对order模块中的GoodsService做如下改造:

package com.felix.service;

import com.felix.model.Goods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * Created by weistekweistek on 2019/1/3.
 */
@Service
public class GoodsService {
    @Autowired
    private RestTemplate restTemplate;

    public Goods findGoodsById(Long id){
        String url = "http://127.0.0.1:8000/goods/"+ id;
        return restTemplate.getForObject(url,Goods.class);
    }
}

在这段代码里面,我们注入了RestTemplate,它帮助我们从指定的接口中请求数据,并且生成一个商品对象并返回。当然,我们需要在OrderApplication中定义restTemplate,下面是OrderApplication改造后的代码

package com.felix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class OrderApplication {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

这样是否就可以了呢?不用怀疑,可以了!下面,我们分别启动商品服务GoodsApplication订单服务OrderApplication,然后访问商品服务的接口http://127.0.0.1:8000/goods/8


商品服务正常,接下来访问订单服务的接口http://127.0.0.1:8001/order/2

可见,订单服务已经可以正常的从商品服务的服务器中取出数据并拼接成订单数据返回给用户了,为了验证订单服务确实从商品服务中自动进行了网络请求,我们在商品服务中的GoodsController打印日志来查看
@RequestMapping(value = "/{id}")
    public Goods findGoodsById(@PathVariable("id") Long id){
        System.out.println("收到商品信息请求");
        return goodsService.findGoodsById(id);
    }

然后重新启动商品服务的服务器,再次请求订单服务的接口http://127.0.0.1:8001/order/3分别查看返回的JSON数据和log信息


切换到商品服务服务器查看log信息

和我们想象的一样,我们只是访问了订单服务的接口,订单服务自动为我们请求了商品服务中的商品信息。
至此,我们完成了订单服务的分离,成功的将传统服务器中的多个服务拆分到了不同的服务器中。那么有个问题,每次进行商品信息请求的时候,难道我都要在订单服务中修改商品服务的地址吗,这样岂不是还是比较麻烦?是的,确实很麻烦,所以,下篇我们将使用SpringCloud中的Eureka的服务注册和发现来解决我们的问题。

分布式系统开发---高可用业务服务器SpringCloud(五)
以上内容转载请注明出处,同时也请大家不吝你的关注和下面的赞赏
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

上一篇下一篇

猜你喜欢

热点阅读