概念(是什么):是JavaEE6标准中一个规范,
作用(干什么):它提供了JavaEE平台上服务注入的组件管理核心,简化应该是CDI的目标,让一切都可以被注解被注入。
和之前接触过的IOC/ID有什么不同
(1)、将依赖注入IOC/DI上升到容器级别,
(2)、概念和我们之前在DCI架构中讨论的业务场景不一样,
包含有容器技术架构场景的意思,场景包括四种:
1、request(event),
importjavax.inject.Named;@NamedpublicclassMessageServerBean{publicStringgetMessage(){return"HelloWorld!";}}
CDI还提供了@Decorator和@Interceptor,这涉及AOP和动态组件的概念。此处不做深入描述
@Named("itemProcessor")@RequestScoped//表示生命周期是request,每次request请求结束,生命就终止,也可以有Session或Application等publicclassItemProcessor{@InjectprivateItemDaoitemDao;//表示ItemDao(业务类)需要被注入//@ANY修饰符//为了提供完全松耦合的应用,我们通常把接口注入到受管理的资源中。//当我们有多个实现了给定接口的bean时该怎么办呢?//我们可以同时使用@Any修饰符和CDI的Instance接口,来把所有该接口的实现bean都注入进一个受管理的bean中:@InjectpublicvoidlistServiceImplementations(@AnyInstance
CDI这种事件模式还是组件(userEvent)驱动领域模型(user),不同于JF是领域模型自身发出事件,这两者还是有本质区别,更加突出领域模型作为业务核心的重要位置,而JavaEE6为了强调其技术架构的重要位置,免不了和业务争夺核心位置,这是我们使用者必须注意的,不能死读标准。
生产者方法的参数也可以经由CDI容器进行注入。请查看JavaEECDIProducermethodstutorial.
CDI创建代理是通过继承原来bean的类,并重写所有非私有方法。一个简单的典型的代理的例子可以像下面这样:
当一个Session范围的bean被注入application范围作用域由于application范围内的bean是共享到整个项目中的如果多个客户
同时访问这个application里面被注入的这个session范围内的bean的话很有可能会造成A用户访问的应该是B用户Session范围bean
的内容、为了处理这种问题CDI创造了代理并把代理注进注入点,由代理负责对应被注入的bean的调用
如下场景代码简单示例为:
@SessionScopedpublicclassService{publicvoiddoWork(){System.out.println("Working...");}}//在application范围内注入了session范围内的bean就造成了我上述的情况@ApplicationScopedpublicclassSomeBean{@InjectprivateServiceservice;//这个注入是存在问题的publicvoidtest(){service.doWork();}}
CDI代理示例
//交给CDI进行代理并重写所有service非私有方法然后以避免此问题发生publicclassService$Proxy$_$$_WeldClientProxyextendsService{@OverridepublicvoiddoWork(){Serviceinstance=//...resolvebeaninstanceinstance.doWork();}}
由于CDI代理通过继承bean的类来创建,所以当我们讨论非依赖性bean范围的时候,你应当明白CDI有如下一些限制: