有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

jakarta ee在JavaEE中与EJB交互的最佳方式

我有一个中等规模的JavaEE6项目,它使用了几个EJB,其中一个唯一的目的是通过JPA管理数据库调用。我的问题是,最好的方法是添加一个新类,该类执行一些随机的功能,然后调用数据库访问EJB来持久化该类中的数据

如果这个新类需要访问注释和注入,它必须是EJB吗?如果它必须与项目的其余部分一起部署,那么它必须是EJB吗

我被告知,如果您想向项目中添加一个新的逻辑类,它必须是一个EJB,或者您可以使用JNDI远程集成它来访问EJB元素并创建某种类型的客户机接口。现在我的新类只是一个POJO,但它不能访问EJB功能

我通常应该做什么

编辑:请注意,我的问题不是关于数据库访问。这只是我正在使用的一个例子。我的问题更广泛。我想知道如何从我创建的其他类访问EJB方法。从一个EJB到另一个EJB,您可以简单地注入另一个EJB,因为它们都是容器管理的。但是假设我在与EJB相同的包中创建了另一个类,那么我如何访问这些方法呢?可能吗?这里的最佳实践是什么

现在我有一个类,它从URL获取twitter提要数据,然后解析JSON并返回前10个条目的字符串。我想调用管理数据库访问的EJB,并将该字符串传递给相应的方法,但我不能这样做,因为我的类不是EJB


共 (1) 个答案

  1. # 1 楼答案

    EJB通常用于实现任何类型的服务。它们与JPA集成得非常好,因此经常用于DB访问,但这不是它们的唯一用途

    EJB通常不适合建模数据。也就是说,它们应该是应用程序中的动词,而不是名词。因此,以下内容是错误的:

    @Stateless
    @Entity
    public class CreditCard { // silly, don't do this!
    
         @Id
         Long id; + getters/setters
         Data expiration date; + getters/setters
    }
    

    更好的是,当应用程序启动时,它可以从某处获取一些报价数据:

    @Singleton
    @Startup
    public class QuoteFetcher {
    
         private List<Quote> quotes; // + getter
    
         @PostConstruct
         public fetchQuote()
              quotes = SomeUrlBuilder.someUrl().getQuotes();
         }
     }
    

    下面是一个示例:

    @Stateless
    public class JPAInvoiceDAO implements InvoiceDAO {
    
         @PersistenceContext
         private EntityManager entityManager;
    
         public Invoice getById(Long invoiceId) {
               return entityManager.find(invoiceId, Invoice.class);
         }
    
         // More DAO methods
    }
    

    下面展示了如何使用声明式安全性,以及bean如何查找外部映射到其私有上下文(ENC)中的内容:

    @Stateless
    public class TokenFetcher
    
        @Resource
        private SessionContext sessionContext;
    
        @RolesAllowed("SYSTEM")
        public Token getToken() {
            return (Token) sessionContext.lookup("token");
        }
    }
    

    问题的第二部分似乎是如何在代码中使用这些bean。基本上有四种方法:

    1. 管理豆子中的注射
    2. 通过JNDI引导
    3. 启动时自动调用
    4. 自动通过计时器

    注入是最简单的方法,但只有托管bean是注入候选对象(基本上意味着JavaEE框架创建bean,而您不使用new()来实例化它)

    例如注射:

    @ManagedBean
    public class InvoiceBacking {
    
         private Long invoiceId; // + getter/setter
         private Invoice invoice; // + getter
    
         @EJB
         private InvoiceDAO invoiceDAO;
    
         @PostConstruct
         public void init() {
              invoice = invoiceDAO.getById(invoiceId);
         }
     }
    

    (另见Communication in JSF 2.0#Processing GET request parameters

    通过JNDI引导:

     public class SomeQuartzJob implements Job {
    
         public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
              InvoiceDAO invoiceDAO = (InvoiceDAO) new InitialContext().lookup("java:global/myApp/myEJB/InvoiceDAO");
              List<Invoice> openInvoices = invoiceDAO.getAllByOpenStatus();
              // verbose exception handling and closing JNDI context omitted for brevity
         }
      }
    

    前面展示的@Singleton bean是JavaEE框架在启动时如何调用代码本身的一个例子。对于自动计时器,可以在bean的方法上使用@Schedule注释