2013-06-21 4 views
0

기본적으로 로컬 인터페이스가있는 @Stateless 빈을 @Named로 주석 된 클래스에 삽입하려고합니다! 제 생각에 주입 지점은 주입 지점을 관리 할 때만 가능합니다 (완벽한 의미를가집니다). 예를 들어 POJO에 주입 할 수 없지만 JSF 관리 또는 다른 EJB 인 Servlet에 주입 할 수 있습니다.왜 @EJB를 @Named와 함께 사용할 수 없습니까?

나중에 @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 사용하여 시도했다 그러나 그 중 하나가 작동하지 않습니다. 사양을 잘못 이해했거나 잘못 구현 한 적이 있습니까?

+0

수업에 어떻게 액세스합니까? EmailUtil은 어디에 주입됩니까? –

+0

Audit EJB를 EmailUtil에 주입하는 데 문제가 없습니다. – tarka

+0

EmailUtil u = new EmailUtil() 주사를 통해 수업에 액세스하는 경우 작동하지 않습니다. 이것이 내가 당신이 어떻게 그것에 접근했는지 알고 싶었던 이유입니다. –

답변

1

종속성을 주입해야합니다. 따라서 EmailUtil을 수동으로 구성하는 경우 주사가 작동하지 않습니다. 컨테이너 관리가 필요합니다. 따라서 서블릿 또는 관리 Bean을 사용하는 경우 @Inject을 사용할 수 있습니다. CDI 삽입은 관리되는 개체에 대해서만 작동합니다.

생성 된 인스턴스에 대해 수동으로 호출하는 등의 추가 작업을 수행 할 수 있습니다. 이 질문을 다음과 같이 예로보십시오. Parallel webservices access in a Weld CDI environment

0

beans.xml이 올바른 위치에 있습니까? @Named (및 다른 CDI 빈즈)에 대한 인젝션은 CDI에 의해 처리된다. CDI는 beans.xml 파일이 올바른 위치 (전쟁 용 WEB-INF 및 jar 용 META-INF)에 있지 않으면 시작되지 않는다.

+0

예 beans.xml은 WEB-INF에 있습니다. 흥미로운 것은'@ Inject'와 같은 다른 CDI 인공물이 작동한다는 것입니다. 그것은 특별히'@ EJB'입니다. 그러므로'@ EJB'의 사용법에 대해 이해할 수없는 것이 있는지 묻는 질문입니다. – tarka

관련 문제