为RestTemplate模拟实现一个LoadBalanced注解

一 新建项目rest-tpl-test
二 新建依赖
<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>org.crazyit.cloud</groupId>
      <artifactId>rest-tpl-test</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <dependencies>
            <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
                  <version>1.5.4.RELEASE</version>
            </dependency>
      </dependencies>
</project>
三 新建启动类
package org.crazyit.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApp {

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

}
四 新建一个注解接口
package org.crazyit.cloud;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Qualifier;

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyLoadBalanced {

}
五 新建一个配置类,用于设置新增的拦截器
package org.crazyit.cloud;

import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;

@Configuration
public class MyConfig {

	@Autowired(required = false)
	@MyLoadBalanced
	private List<RestTemplate> tpls = Collections.emptyList();
	
	@Bean
	public SmartInitializingSingleton lbInitializing() {
		return new SmartInitializingSingleton() {

			public void afterSingletonsInstantiated() {
				for(RestTemplate tpl : tpls) {
					List<ClientHttpRequestInterceptor> interceptors = tpl.getInterceptors();
					interceptors.add(new MyInterceptor());
					tpl.setInterceptors(interceptors);
				}
			}
			
		};
	}
}
六 新建控制器,能够实现转发功能
package org.crazyit.cloud;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@Configuration
public class MyController {

    @Bean
    @MyLoadBalanced
    public RestTemplate tplA() {
        return new RestTemplate();
    }
    
    @RequestMapping(value = "/call", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String call() {
        RestTemplate tpl = tplA();
        String json = tpl.getForObject("http://hello-servie/call", String.class);
        return json;
    }
    
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "Hello World";
    }

}
七 新建一个拦截器,实现转发功能
package org.crazyit.cloud;

import java.io.IOException;
import java.net.URI;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

public class MyInterceptor implements ClientHttpRequestInterceptor {

    public ClientHttpResponse intercept(HttpRequest request, byte[] body,
            ClientHttpRequestExecution execution) throws IOException {
        System.out.println("===============  这是自定义拦截器");
        System.out.println("         旧的uri:" + request.getURI());
        
        HttpRequest newRequest = new MyRequest(request);
        System.out.println("         新的uri:" + newRequest.getURI());
        
        return execution.execute(newRequest, body);
    }

}
八 新建MyRequest
package org.crazyit.cloud;

import java.net.URI;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;

public class MyRequest implements HttpRequest {
    
    HttpRequest sourceRequest;
    
    public MyRequest(HttpRequest sourceRequest) {
        this.sourceRequest = sourceRequest;
    }

    public HttpHeaders getHeaders() {
        return sourceRequest.getHeaders();
    }

    public HttpMethod getMethod() {
        return sourceRequest.getMethod();
    }

    public URI getURI() {
        try {
            URI newUri = new URI("http://localhost:8080/hello");
            return newUri;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sourceRequest.getURI();
    }

}
九 启动项目
十 测试实现转发功能的拦截器
控制台输出
===============  这是自定义拦截器
         旧的uri:http://hello-servie/call
         新的uri:http://localhost:8080/hello

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/81055439