简体   繁体   中英

Cannot find CDI beans

I created this simple CDI bean:

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;


    @Named("DashboardController")
    @ViewScoped
    public class Dashboard implements Serializable
    {
    .......
    }

I removed all configuration from faces-config.xml. I created this beans.xml file into WEB-INF directory:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

When I opened the JSF page the bean cannot be found. Can you tell me what am I missing? I don't want to declare the beans into faces-config.xml.

PS I don't know if this is important or not but this is a WAB package with CDI beans.

You'll need to use ViewAccessScoped instead of ViewScoped.

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;
//Note the different import
import javax.faces.context.FacesContext;
import javax.inject.Named;


    @Named("dashboardController")
    @ViewAccessScoped
    public class Dashboard implements Serializable
    {
    .......
    }

You should also start the name in Named with a non-capital letter.

You might need to add the faces_config file to your META-INF folder of your WAB as described in this thread

That aside, even if the bean is found, you might still have problems with the scoping; You can't apply a JSF scope to a CDI bean. CDI's @ConversationScoped is a somewhat less than convenient alternative to JSF's @ViewScoped . The inconvenience of the scope lies in the fact that you need to inject an extra managed object and you have to actively manage the scope yourself. To use:

  1. Annotate your bean with @ConversationScoped

     @Named("DashboardController") @ConversationScoped public class Dashboard implements Serializable { } 
  2. Inject the Conversation object into your bean

     @Inject private Conversation conversation; 
  3. On this object, you need to call begin() and end() to start the "conversation" (a la viewscope) and "end" the conversation (like JSF does by destroying a viewscoped bean) respectively. This is a matter of design and context. At the very least, you can call conversation.begin() in a @PostConstructor . Where you end the conversation depends on your specific use case

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM