OpenFeign 快速入门

OpenFeign 快速入门

  • OpenFeign 是什么,解决了什么问题?
  • OpenFeign 插件列表
  • OpenFeign Vs Spring RestTemplate
  • OpenFeign Demo

 

OpenFeign是什么,它解决了什么问题?

OpenFeign是为了方便 HTTP、Restful调用而产生的,使用它,在访问一个http 服务时,不需要写了一大队的代码。使用它可以扔掉Webservic , jaxrs 等技术的客户端了,可以不用直接使用 httpclient了。

  

OpenFeign 插件列表

 

支持的插件说明:

1) 可以与多种HttpClient配合使用:

      + Jdk HTTPURLConnction 默认

      + Apache HttpClient 4,5

      + OKHttp

      + google httpclient

2) 可以与多种JSON框架结合使用

      + Gson

      + Jackson

      + Easyjson (一个JSON库的门面,类似的slf4j)

3) 支持SOAP、XML消息

4)可以与Ribbon结合,提供负载均衡功能

    如果对feign-ribbon进行扩展,就能实现服务发现功能,动态路由功能。

 

5)可以与hystrix结合,提供熔断功能

6)可以与dropwizard-metric 结合提供监控功能

7)提供了jaxrs插件,用于支持使用jaxrs规范的注解来替代默认的注解

 

 

OpenFeign Vs Spring RestTemplate?

 

 

 

OpenFeign Demo

网上很多都是 Spring Cloud下的demo,那么非 Spring Cloud环境下该如何使用呢?下面就给出这样一个例子,所用技术:Spring Boot + Apache DBUtils + SqlHelper + EasyJson + OpenFeign + Jackson。

 

+ Spring Boot 快速开发环境。

+ Apache DBUtils 提供统一的数据库访问功能,数据库用h2。

+ SqlHelper 提供统一的分页功能

+ EasyJson 提供统一的 JSON 门面,Jackson 提供 JSON 转换底层实现。

+ OpenFeign 提供 统一的 Http访问门面, JDK HttpUrlConnection 提供http访问底层实现。

+ Slf4j 提供 统一的 logger 门面,logback提供 日志访问底层实现。

  

下面列出服务端代码:

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private QueryRunner queryRunner;

    @Autowired
    @Qualifier("sqlMap")
    private Map<String, String> sqlMap;


    @PostMapping()
    public void add(User user) throws Throwable {
        queryRunner.insert(
                sqlMap.get("user.insert"),
                new UpdatedRowsResultSetHandler(),
                user.getId(), user.getName(), user.getAge());
    }

    @PutMapping("/{id}")
    public void update(String id, User user) throws Throwable {
        user.setId(id);
        User u = getById(id);
        if (u == null) {
            add(user);
        } else {
            queryRunner.update(sqlMap.get("user.updateById"),
                    user.getId(), user.getName(), user.getAge(),
                    user.getId()
            );
        }
    }

    @DeleteMapping("/{id}")
    public void deleteById(@RequestParam("id") String id) throws Throwable {
        queryRunner.update(sqlMap.get("user.deleteById"), id);
    }

    @GetMapping("/_all")
    public List<User> all() throws Throwable {
        return queryRunner.query(sqlMap.get("user.selectAll"),
                new RowMapperResultSetHandler<User>(new BeanRowMapper<User>(User.class))
        );
    }

    @GetMapping()
    public PagingResult list_useApacheDBUtils(
            @RequestParam(name = "pageNo", required = false) Integer pageNo,
            @RequestParam(name = "pageSize", required = false) Integer pageSize,
            @RequestParam(name = "sort", required = false) String sort,
            @RequestParam(name = "testSubquery", required = false, defaultValue = "false") boolean testSubquery) throws SQLException {
        PagingRequest request = SqlPaginations.preparePagination(pageNo == null ? 1 : pageNo, pageSize == null ? -1 : pageSize, sort);
        if (testSubquery) {
            request.subqueryPaging(true);
        }
        StringBuilder sqlBuilder = testSubquery ? new StringBuilder("select * from ([PAGING_START]select ID, NAME, AGE from USER where 1=1 and age > ?[PAGING_END]) n where name like CONCAT(?,'%') ") : new StringBuilder("select ID, NAME, AGE from USER where 1=1 and age > ?");
        List<Object> params = Collects.emptyArrayList();
        params.add(10);
        if (testSubquery) {
            params.add("zhangsan");
        }

        List<User> users = queryRunner.query(sqlBuilder.toString(),
                new RowMapperResultSetHandler<User>(new BeanRowMapper<User>(User.class)),
                Collects.toArray(params)
        );

        String json = JSONBuilderProvider.simplest().toJson(users);
        System.out.println(json);
        return request.getResult();
    }


    @GetMapping("/{id}")
    public User getById(@PathVariable("id") String id) throws Throwable {
        List<User> users = queryRunner.execute(
                sqlMap.get("user.selectById"),
                new SingleRecordRowMapperResultSetHandler<User>(new BeanRowMapper<User>(User.class)),
                id
        );
        return Collects.findFirst(users, Functions.nonNullPredicate());
    }

}
View Code

 

下面列出 client代码:

public interface UserClientService {
    @RequestLine("GET /users?pageSize=10&pageNo=1")
    public PagingResult<User> getUsers();

    @RequestLine("GET /users?pageSize=10&pageNo={pageNo}}")
    public PagingResult<User> queryUsers(@Param("pageNo") int pageNo);

    @RequestLine("GET /users/{id}")
    public User getById(@Param("id") String id);

    @RequestLine("POST /users")
    public void add(User user);

    @RequestLine("PATCH /users")
    public void update(User user);
}


public class UserClientServiceTests {

    private static JSONFactory jsonFactory;
    private static Feign feign;
    private static UserClientService userClientService;
    private static JSON jsons;

    static {
        JSONBuilder jsonBuilder = JSONBuilderProvider.create().enableIgnoreAnnotation();
        jsonFactory = JsonFactorys.getJSONFactory(jsonBuilder, JsonScope.SINGLETON);
        jsons = jsonFactory.get();
    }

    @BeforeClass
    public static void init() {
        feign = Feign.builder()
                .decoder(new EasyjsonDecoder(jsonFactory))
                .build();
        Target<UserClientService> webTarget = new Target.HardCodedTarget(UserClientService.class, "userService", "http://localhost:8080/");
        userClientService = feign.<UserClientService>newInstance(webTarget);
    }

    @Test
    public void testPagination() {
        System.out.println(jsons.toJson(userClientService.getUsers()));
    }

    @Test
    public void testGetById() {
        System.out.println(jsons.toJson(userClientService.getById("0001")));
    }

}

完整的测试用例:

https://github.com/fangjinuo/sqlhelper

sqlhelper-examples-service-apachedbutils提供 服务端

sqlhelper-examples-client-feign 提供客户端

 

posted @ 2020-06-22 17:36  乐享程序员  阅读(1109)  评论(0编辑  收藏  举报