为什么我不能在@Named中使用@EJB?

时间:2013-06-21 08:08:46

标签: ejb glassfish-3 cdi named

我基本上尝试将带有本地接口的@Stateless bean注入到使用@Named注释的类中!我的理解是注入只有在注入点被管理时才有可能(完全合理),所以例如注入POJO是不可能的,但你可以注入到Servlet,JSF托管或另一个EJB中

我原本以为随后可以将它与@Named一起使用!但是我得到一个NullPointerException,特别暗示这实际上似乎不可能!?

我的课程看起来像这样(为了清晰起见而剥离);

@Named
public class EmailUtil {

// Logger-------------------------------------------------------------------
private static final Logger LOG = Logger.getLogger(EmailUtil.class.getName());

// Constructor--------------------------------------------------------------
public EmailUtil() {
}

// EJB----------------------------------------------------------------------
@EJB AuditDAO audit;

// Methods------------------------------------------------------------------
public void sendEmail(
        String emailSender,
        String emailRecipient,
        String emailSubject,
        String emailHtmlBody,
        String emailTextBody) throws FailedEmailException {

    ... code removed for clarity ...

    // Call Amazon SES to send the message 
    try {
        new SES().getClient().sendEmail(request);

        // Create an audit log of the event
        audit.create("Email sent to " + emailSender);
    } catch (AmazonClientException ace) {
        LOG.log(Level.SEVERE, ace.getMessage(), ace);
        throw new FailedEmailException();
    } catch (Exception e) {
        LOG.log(Level.SEVERE, e.getMessage(), e);
    }
}
}


@Stateless
public class AuditDAOImpl implements AuditDAO {

    // Logger-------------------------------------------------------------------
    private static final Logger LOG = Logger.getLogger(AuditDAOImpl.class.getName());
    // EntityManager------------------------------------------------------------
    @PersistenceContext(unitName = "iConsultPU")
    private EntityManager em;

    @Override
    public void create(String event) {
        String subject;
        try {
            /*
             * If the current subject has authenticated and created a session we
             * want to register their ID. However it is possible that a subject
             * does not have an ID so we want to set it to unknown.
             */
            subject = SecurityUtils
                    .getSubject()
                    .getPrincipals()
                    .asList()
                    .get(1)
                    .toString();
        } catch (Exception e) {
            subject = "UNKNOWN";
        }

        Audit audit = new Audit();
        audit.setUserId(subject);
        audit.setEventTime(Calendar.getInstance());
        audit.setEvent(event);

        em.persist(audit);

    }
}

@Local
public interface AuditDAO {
    public void create(String event);    
}

我也试过使用@Inject,但这似乎也没有用。我误解了规范还是实施得不好?

2 个答案:

答案 0 :(得分:1)

你应该注入你的依赖项。因此,如果您的EmailUtil是手动构建的,则注射不会起作用。它需要进行容器管理。因此,如果您使用servlet或任何托管bean,则可以@Inject它。 CDI注入仅适用于托管对象。

您可以执行一些额外的解决方法,例如针对构造的实例手动调用它。看看这个问题就像这样的例子:Parallel webservices access in a Weld CDI environment

答案 1 :(得分:0)

您是否将beans.xml放在正确的位置? @Named(和其他CDI bean)的注入由CDI处理,除非你将beans.xml文件放在正确的位置(战争的WEB-INF和jar的META-INF),否则不会启动注入。