【问题标题】:How to create a dynamic proxy of a already proxyed class in spring如何在spring中创建已经代理的类的动态代理
【发布时间】:2020-01-13 05:50:36
【问题描述】:

我对弹簧/弹簧靴比较陌生。

目前我正在使用 Spring Boot Rest 应用程序,它提供 FeignClient 以包含在其他项目中。现在,我希望这些 FeignClient 被 CircuitBreaker 包裹起来。

我想出的最佳解决方案是我动态创建一个代理,其中包括 CircuitBreaker 实现,它本身调用创建的 FeignClient。

假设我有以下描述 RestController 的接口:

@RequestMapping("/")
public interface MyWebService {

    @GetMapping("name")
    public String getName();
}

现在,我有了 FeignClient 的接口:

@FeignClient("app")
public interface WebServiceClient extends WebService {
}

所以.. 我的目标是实现类似我有另一个注释 e。 G。 @WithCircuitBreaker 然后我将被扫描并动态创建一个代理 bean,它将被注入而不是 FeignClient bean。

目前我的代码如下所示:

@FeignClient("app")
@WithCircuitBreaker
public interface WebServiceClient extends WebService {
}

据我所知,我现在可以创建一个如下所示的@Configuration 类:

@Configuration
public class WithCircuitBreakerConfiguration implements ImportAware {

    private AnnotationMetadata annotationMetadata;
    private AnnotationAttributes annotationAttributes;

    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {
        this.annotationMetadata = importMetadata;
        Map<String, Object> annotatedClasses = importMetadata.getAnnotationAttributes(WithCircuitBreaker.class.getName());
        this.annotationAttributes = AnnotationAttributes.fromMap(annotatedClasses);
    }

    What else to import to create the proxy and inject it?
}

现在我到了重点,我不知道如何继续。如何动态创建一个代理类来做这样的事情:

public class PorxyedWebService {

    private WebService feignClientProxy;

    @Autowired
    public ProxyedWebService(WebService feignClientProxy) {
        this.feignClientProxy = feignClientProxy;
    }

    public String getName() {
        ...
        <some circuitbreaker stuff>
        ....
        return this.feignClientProxy.getName();
    }
}

然后一旦有人自动连接WebService 接口,就返回这个代理而不是从 Feign 生成的代理。

【问题讨论】:

    标签: java proxy spring-cloud feign resilience4j


    【解决方案1】:

    我不是 Spring 用户,但我知道 Spring 确实不递归地创建代理,例如多个 Spring AOP 方面应用于同一个对象。相反,在同一个代理上注册了额外的拦截器(或 AOP 语言中的通知)。我认为您想使用该基础架构来实现您的目标。

    【讨论】:

      【解决方案2】:

      您可以只使用弹性 4j Spring Boot2 启动器。 您可以在接口级别将@CircuitBreaker 注解与@FeignClient 注解结合起来。

      然后您可以按如下方式使用它:

      @FeignClient(name = DUMMY_FEIGN_CLIENT_NAME)
      @CircuitBreaker(name = DUMMY_FEIGN_CLIENT_NAME)
      public interface DummyFeignClient {
      
          String DUMMY_FEIGN_CLIENT_NAME = "dummyFeignClient";
      
          @GetMapping(path = "/api/{param}")
          void doSomething(@PathVariable(name = "param") String param);
      } 
      
      

      【讨论】:

        猜你喜欢
        • 2013-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-17
        • 2020-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多