什么 Weld CDI 可以 @Inject 而不在 JSF 2.1+ 应用程序中声明 @Produces?
据我了解,它可以在正确设置的 Web 应用程序中注入 FacesContext。
能不能注入:
- Http会话?
- 来自 web.xml 的上下文参数(ala ServletContext.getInitParameter(xxx))
- 来自 web.xml 的 env-ref
什么 Weld CDI 可以 @Inject 而不在 JSF 2.1+ 应用程序中声明 @Produces?
据我了解,它可以在正确设置的 Web 应用程序中注入 FacesContext。
能不能注入:
据我测试(也根据Weld Spec 1.1 ),您可以在 Java EE 环境中注入javax.security.Principal
和。javax.transaction.UserTransaction
这在带有 CDI 版本的 JBoss AS 7.2 上对我来说很好1.1-PRD
。
对于 Servlet 容器,有责任使这些对象可注入到您的应用程序中
javax.servlet.http.HttpServletRequest
javax.servlet.http.HttpSession
javax.servlet.ServletContext
然而,并不是每个容器都能真正支持这一点(而且我也没有对此进行测试,但我认为它应该可以工作——我已经在某处看到过这段代码)。
好的,这是我自己对这个问题的回答。
有孵化的Apache项目DeltaSpike。
DeltaSpike 由许多可移植的 CDI 扩展组成,这些扩展为 Java 应用程序开发人员提供了有用的特性。
根据文档,Servlet 模块允许注入 ServletContext、HttpSession 和 Principal 对象。
但是,我采用了不同的路径并自己实现了上下文参数注入,使用带有 InjectionPoint 参数的@Producer 方法。这真的很简单。
首先为参数创建一个注释,该注释将包含上下文参数名称属性。
@Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface WebContextParameter {
@Nonbinding String value() default "";
}
必须声明注释属性 name(),@Nonbinding
以便 CDI 不会将其用作限定过程的一部分。
二、使用@Produce方法创建producer bean
public class WebContextParameterProducer {
@Inject
private ServletContext context;
@Produces
@WebContextParameter()
public String createWebContextParameter(InjectionPoint ip) {
WebContextParameter annotation = null;
for (Iterator<Annotation> it = ip.getQualifiers().iterator(); it.hasNext();) {
Annotation n = it.next();
if (n.annotationType().equals(WebContextParameter.class)) {
annotation = (WebContextParameter) n;
break;
}
}
return context.getInitParameter(annotation.value());
}
}
之后,在代码中的任何位置使用:
@Inject
@WebContextParameter("my.config.option")
String myConfigOption = "default-value";
但是请注意,“默认值”仅用于非 CDI 环境。在 CDI 中,如果在 web.xml 中找不到任何值,myConfigOption
则将设置为。null
可以扩展此示例defaultValue()
,向注释添加附加属性以缓解此问题。
所以基本上,ServletContext 已经是@Inject-able,所以它的其余部分也是可注入的。