通过MicroProfile上下文传播增强了CDI上下文和隔板

当将CDI与异步执行方法(例如ManagedExecutorService ,传统上不可能访问在原始线程中处于活动状态的所有CDI范围。 MicroProfile Context Propagation可以定义线程执行上下文并将其传递到完成阶段,尽管我们的代码是异步执行的,但它们仍可以访问各种CDI上下文。 另外,Context Propagation允许创建托管的执行器服务,该服务可以注入到我们的bean中并在其中使用,例如实现舱壁。

增强的CDI上下文

让我们创建并使用在处理请求期间使用的请求范围的Bean。 使用普通的CDI,我们将无法在异步执行中访问和查找bean。

看下面的代码:

 @ApplicationScoped  @Path ( "contexts/example" )  public class ThreadContextExampleResource { 
     @Inject 
     ExampleStore exampleStore; 
     @Inject 
     ThreadContext threadContext; 
     @Resource 
     ManagedExecutorService mes; 
     @Inject 
     Notifier notifier; 
     @PUT 
     public void setExample(String example) { 
         exampleStore.setExample(example); 
         mes.execute(threadContext.contextualRunnable(notifier::notifyAbout)); 
     }  } 
 @RequestScoped  public class ExampleStore { 
     private String example; 
     public String getExample() { 
         return example; 
     } 
     public void setExample(String example) { 
         this .example = example; 
     }  } 
 public class Notifier { 
     @Inject 
     ExampleStore exampleStore; 
     public void notifyAbout() { 
         System.out.println( "New example: " + exampleStore.getExample()); 
     }  } 

如果客户端PUTcontexts/example资源提供了某些内容,则该方法将使用ManagedExecutorService更新请求范围的ExampleStore bean并异步执行通知。 为了使异步执行能够查找请求范围的存储,我们使用ThreadContext将可运行对象与从原始线程捕获的上下文进行包装。 这样可以确保执行的可运行对象可以使用相应的上下文。

我们必须根据要传播的上下文类型(例如CDItransactionsecurity )配置并产生ThreadContext

 public class ThreadContextProducer { 
     @Produces 
     ThreadContext threadContext() { 
         return ThreadContext.builder() 
                 .propagated(ThreadContext.ALL_REMAINING) 
                 .build(); 
     }  } 

本示例将所有上下文类型传播到包装的执行中。 然后,我们的bean注入并使用产生的ThreadContext

使用执行程序定义舱壁

MicroProfile Context Propagation允许创建和配置ManagedExecutor ,这是类似于ManagedExecutorService的容器管理的执行器服务。 我们可以通过编程方式创建ManagedExecutor ,对允许的并发设置约束,并定义上下文传播。

通过使用专用执行器来实现特定功能,我们可以实现隔板模式,类似于使用MicroProfile Fault TolerancePorcupine

让我们定义以下异步JAX-RS资源:

 @ApplicationScoped  @Path ( "bulkheads" )  public class BulkheadExampleResource { 
     @Inject 
     ExampleStore exampleStore; 
     @Inject 
     Notifier notifier; 
     @Inject 
     ManagedExecutor writeExecutor; 
     @Inject 
     ManagedExecutor readExecutor; 
     @GET 
     public CompletionStage<String> example() { 
         return readExecutor.supplyAsync(exampleStore::getExample); 
     } 
     @PUT 
     public CompletionStage<Void> setExample(String example) { 
         return writeExecutor.runAsync(() -> { 
             exampleStore.setExample(example); 
             writeExecutor.execute(notifier::notifyAbout); 
         }); 
     }  } 

我们正在注入两个专用的执行器,它们用于运行相应的功能。 执行者是使用生产者创建的:

 public class ManagedExecutorProducer { 
     @Produces 
     ManagedExecutor managedExecutor() { 
         return ManagedExecutor.builder() 
                 .propagated(ThreadContext.CDI, ThreadContext.APPLICATION) 
                 .maxAsync( 4 ) 
                 .maxQueued( 4 ) 
                 .build(); 
     } 
     public void disposeManagedExecutor( @Disposes ManagedExecutor managedExecutor) { 
         managedExecutor.shutdownNow(); 
     }  } 

我们的执行者将具有四个同时执行的完成阶段和四个任务的上限。 CDI的上下文和应用程序上下文类型将传播到执行线程。

注入执行程序时,请注意注入点的范围; 这里我们使用的是应用程序范围的资源,否则我们可能会创建两个以上的执行程序,这将违反隔板模式的目的。 由于我们使用的是CDI,因此,如果应以不同的方式配置所创建的执行程序,则当然可以定义其他限定符。

您可以使用最新版本的Open Liberty试用MicroProfile Context Propagation。 我已经在GitHub上发布了一个示例存储库。

当我们在Open Liberty上运行应用程序时,MicroProfile Context Propagation执行程序将由自动调整的全局线程池提供支持。 你可以看看由自由所提供的默认线程池的指标,如图所示这里

更多资源

翻译自: https://www.javacodegeeks.com/2019/08/enhanced-cdi-contexts-bulkheads-microprofile-context-propagation.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值