cdi 2.7.5
CDI是最近对Java EE最好的补充之一。 该观点在用户和集成商之间广泛共享。 当前版本的CDI 1.2于2014年4月发布。现在,在2015年中期,我们将面对CDI 2.0规范的早期草案。 CDI 2.0将在Java 8和更高版本上运行。
最终版本计划于2016年发布,该路线图包含几个有趣的项目:
- 将API分为Java SE和Java SE两部分:拆分API是支持微服务移动的重要步骤。 从几行中的每个
main()
引导CDI。 - 异步事件和优先事件允许控制事件观察者的排序和异步事件传递
- JDK 8:CDI 1.x针对Java 1.6及更高版本。 Java 8进行了大量改进,并有助于简化CDI的API。
- CDI允许从起源开始扩展。 SPI非常适合使用DeltaSpike,Spring Data,Camel,CDI度量标准等框架来增强CDI。 CDI 2.0旨在改善对扩展的支持
- 你知道吗? CDI大量使用AOP来实现非常舒适的使用。 所有常规范围(例如RequestScoped,ConversationScoped,SessionScoped和ApplicationScoped)都使用代理来查找上下文实例。 但是一个极限规格是,CDI不允许在本地方法调用上进行自我注入或拦截。 AOP软件包将解决这些问题并改进规范的某些部分。
但是,让我们来看看CDI 2.0 EDR的API(早期草案审查),它是新的且值得注意的 。
异步事件
异步事件是CDI用户希望列表上的第一项。 该问题在2011年初提出,是CDI 2.0的重点之一。 为了启用异步处理的事件并通过引入异步性不破坏现有代码,必须进行大量热烈讨论。 当前草案需要双端激活
public class AsyncEvents {@Injectprivate Event<MyEventPayload> event;public void triggerEvent() {event.fireAsync(new MyEventPayload());}public void asyncEventObserver(@ObservesAsync MyEventPayload payload) {System.out.println("Yay, I'm called async!");}public void eventObserver(@Observes MyEventPayload payload) {System.out.println("Yay, I'm called too. " + "Other @Observes are notified in order.");}public static class MyEventPayload {}
}
可以通过对启用了异步功能的观察者的异步处理来触发事件。 使用@Observes
观察者也会在调用线程中得到通知。 可以使用调用fireAsync
时返回的CompletionStage
跟踪异步事件观察器的CompletionStage
fireAsync
。
当事件处理处于活动状态时,异步事件观察器可以在上下文Bean实例上进行操作。 默认情况下,启用的范围是@RequestScoped
和@ApplicationScoped
。 该@SessionScoped
被排除variuous原因。 只要考虑一下会话在事件处理过程中结束时的行为方式即可。 在上下文实例中修改事件有效负载或数据时,用户应注意效果。 CDI不会强制事件有效负载保持不变,但强烈建议您避免由于并发而导致竞争情况。
CDI容器负责提供多线程基础结构。 有时,您想提供一个自己的执行程序来控制并发级别或包装异步调用。 fireAsync
方法允许为每个调用指定单独的执行程序。
private ExecutorService executor;@Injectprivate Event<MyEventPayload> event;@PostConstructpublic void postConstruct() {int threads = Runtime.getRuntime().availableProcessors();executor = new ThreadPoolExecutor(threads, threads, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>());}@PreDestroypublic void preDestroy() {executor.shutdown();}public void triggerEventWithExecutor() {event.fireAsync(new MyEventPayload(), executor);}
上面的示例创建/销毁执行器。 您可以将CDI管理的执行器与生产者方法( @Produces
)结合使用,并在需要的地方@Inject
。 CDI很酷,是吗?
异步事件将仍然是一个热门话题,这肯定不是其最终形式。
有序事件观察者
在CDI 1.2中,使用事件观察器时的通知顺序是不可预测的。 在2.0中,这将发生变化。
public class PrioritizedEvents {@Injectprivate Event<MyEventPayload> event;public void trigger() {event.fire(new MyEventPayload());}public void observeBeforeOtherObservers(@Observes @Priority(Interceptor.Priority.APPLICATION + 499) MyEventPayload payload) {System.out.println("Notified before all other observers");}public void observeAfterOtherObservers(@Observes @Priority(Interceptor.Priority.APPLICATION + 501) MyEventPayload payload) {System.out.println("Notified after all other observers");}public static class MyEventPayload {}
}
事件观察者的顺序可以通过应用@Priority
注释来影响。 为什么受到影响却不受控制?
这个问题的答案更长一些,您需要了解CDI的类型安全解析部分。 事件观察者是根据其事件有效负载类型选择的。 事件观察者可以观察不同的类型,接口,类,子类型,合格和不合格类型。 通过使用Event
或BeanManager
API,将在Event
触发时选择事件观察器。 您可以通过使用类型或其子类型来通知另一组事件观察者。 因此,没有可用的全局事件观察者顺序,这导致我们使用@Priority
批注。
通过应用@Priority
可以提前通知某些事件观察者,并在以后通知某些事件观察者。 默认值为Interceptor.Priority.APPLICATION + 500
,结果为2500
。 这是所有不带有@Priority
批注的事件观察器的默认设置。
仔细观察@Priority
发现,它仅适用于当前类型。 这将一直更改到CDI 2.0最终版本为止。
Java SE的CDI
JavaSE的CDI从一开始就可用,或者我这样说:您可以在JavaSE中启动Weld和OpenWebBeans,而无需JavaEE容器。 CDI 2.0仅指定了以标准方式引导CDI容器的标准方法。 这是我个人的最爱。
public class CDIJumpStart {public static void main(String[] args) {try(CDI<Object> cdi = CDI.getCDIProvider().initialize()) {cdi.select(MyApp.class).get().runMyApplication();}}private static class MyApp{public void runMyApplication(){// ...}}
}
该代码将启动CDI容器并调用一种方法来运行您的应用程序。 应用程序完成后,将使用try-with-resources
模式关闭容器。 用来启动一个独立的,可能是微服务式应用程序的代码比Spring Boot长两行。 与Spring或Dropwizard的主要区别在于生态系统,我找不到现成的嵌入式Tomcat的集成。 我猜想,要成为JavaSE的CDI成为真正的微服务框架之类的替代品,需要花费一些时间。
结论
CDI 2.0 EDR只是正在进行的JSR365努力的一小部分。 有很多问题需要讨论和说明。 JBoss的Weld团队会为规范的发展而努力,并会在将来的某个地方提出RI。 对于Java EE和SE,CDI是一个热门话题,并且仍然非常有吸引力。 请继续关注并遵循CDI 2.0
联系CDI规范:
- Spec网站: http : //www.cdi-spec.org/
- GitHub: https : //github.com/cdi-spec/cdi
- 主要邮件列表: https : //lists.jboss.org/mailman/listinfo/cdi-dev
- CDI 2.0 JCP页面: http : //jcp.org/en/jsr/summary? id = 365
- IRC:irc://freenode.net/#cdi-dev
- 推特:@cdispec
- Google+: https : //plus.google.com/+CdiSpecOrgPage/posts
翻译自: https://www.javacodegeeks.com/2015/09/a-look-on-cdi-2-0-edr1.html
cdi 2.7.5