Based on CDI bean in JSF

I am having problems getting CDI working in a JSF project. I cannot get CDI to inject an interface based bean into the JSF file.

@Named
public class ClassBasedNamedBean {
    public String getMessage() {
        return "Class-based Hello World!";
    }
}

@Named
public interface InterfaceBasedNamedBean {
    public String getMessage();
}

public class InterfaceBasedNamedBeanImpl implements InterfaceBasedNamedBean {
    @Override
    public String getMessage() {
        return "Interface-based Hello World!";
    }
}

      

I can use both beans in the WebServlet environment:

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
    @Inject
    private ClassBasedNamedBean classBasedNamedBean;

    @Inject
    private InterfaceBasedNamedBean interfaceBasedNamedBean;

    protected void doGet(...) ... {
        PrintWriter pw = response.getWriter();
        pw.println("classBasedNamedBean: " + classBasedNamedBean.getMessage());
        pw.println("interfaceBasedNamedBean: " + interfaceBasedNamedBean.getMessage());

        // Output:
        // classBasedNamedBean: Class-based Hello World!
        // interfaceBasedNamedBean: Interface-based Hello World!
    }
}

      

But interfaceBasedNamedBean

not available on JSF page:

<p>ClassBasedNamedBean: #{classBasedNamedBean.message}</p>
<p>InterfaceBasedNamedBean: #{interfaceBasedNamedBean.message}</p>

Output:
<p>ClassBasedNamedBean: Class-based Hello World!</p>
<p>InterfaceBasedNamedBean: </p>

      

How can I fix this problem? Does JSF require explicit configuration for interfaceBasedNamedBean

?

+3


source to share


4 answers


What do I think best:

I don't think this is mentioned in the spec, but I'm pretty sure it is @Named

not intended to be used on interfaces.



At the end of the day, it's just a correspondence between type and EL name - and it seems that EL resolver can't find anything (specific) called interface name.

So, try annotating the implementation, not the interface - it should work. If you need to be flexible with different implementations of the same bean type - inject it into the controller bean and make the bean available.

+2


source


Have you set javax.enterprise.inject.spi.BeanManager

as your BeanManager?

What happens if you add @Named("InterfaceBasedNamedBean")

to the class definition and remove the annotation from the interface? For what reason are you using annotations? CDI does not require them, unlike spring.



Have you tried using the manufacturer's method?

+1


source


Try adding a scope to your bean using @RequestScoped for example. From Weld docs:

@Named annotations are not what class a bean does. Most of the classes in the bean archive are already recognized as beans. @Named annotations simply allow you to reference the bean to EL, most often from a JSF view.

0


source


CDI defines @Named as a String-based classifier. The purpose of the classifier is to distinguish which implementation to use at the injection point. The @Named javadoc provides an example:

public class Car {
   @Inject @Named("driver") Seat driverSeat;
   @Inject @Named("passenger") Seat passengerSeat;
   ...
}

      

Thus, @Named must annotate the concrete implementation.

@Named as a way of using CDI beans in JSF views can be thought of as a secondary function. @Named is not "@Inject for JSF" as it might seem.

0


source







All Articles