문제

What Weld CDI can @Inject without declaring a @Produces in JSF 2.1+ application?

As I understand, it can inject FacesContext in properly set up web application.

Can it inject:

  • HttpSession?
  • context-param from web.xml (ala ServletContext.getInitParameter(xxx))
  • env-ref from web.xml
도움이 되었습니까?

해결책

As far as I tested (and also according to the Weld Spec 1.1) you can inject javax.security.Principal and javax.transaction.UserTransaction in Java EE environment. This works for me fine on JBoss AS 7.2 with CDI version 1.1-PRD.

And for the Servlet container, it is it's responsibility to make these objects injectable for your application

  • javax.servlet.http.HttpServletRequest
  • javax.servlet.http.HttpSession
  • javax.servlet.ServletContext

However, not every container can really support this (and also I didn't test this but I suppose it should work - I've already seen this code somewhere).

다른 팁

Ok, here is my own answer to this question.

There is incubating Apache project DeltaSpike.

DeltaSpike consist of a number of portable CDI extensions that provide useful features for Java application developers.

According to the documentation, the Servlet module allows injection of ServletContext, HttpSession and Principal objects.

However, I have taken a different path and implemented context parameter injection myself, using @Producer method with InjectionPoint argument. It is rather simple really.

First create a annotation for parameter which will hold context-param name attribute.

@Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface WebContextParameter {
    @Nonbinding String value() default "";
}

Annotation attribute name() must be declared as @Nonbinding so CDI will not use it as part of qualifying process.

Second, create producer bean with @Produce method

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());
    }
}

After that, use anywhere in your code:

@Inject
@WebContextParameter("my.config.option")
String myConfigOption = "default-value";

Please note, however, the "default-value" will be used only in non CDI environment. In CDI, myConfigOption will be set to null if no value will be found in web.xml. This example can be expanded adding additional defaultValue() attribute to annotation to alleviate this.

So basically, ServletContext is already @Inject-able, so the rest of the stuff from it is injectable too.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top