Những tính năng mới trong EJB 3.1


Những tính năng mới trong EJB 3.1

Trong loạt bài của articles này ta xem trước những thay đổi ejb3.1 Nhóm chuyên gia đang làm việc cho phiên bản kế tiếp của đặc tả JEE. Đây là các tính năng được cung cấp cho bạn để có thể có ý kiến và phản hổi lại nhóm chuyên gia để có những thay đổi phù hợp. EJB3.0 mang lại tính đơn giản cho JEE5 bằng cách chuyển mô hình lập trình hạng nặng dễ dàng hơn. EJB3.1 nhắm tới việc xây dựng trên những thành công của EJB3 bằng cách tiếp tục đơn giản hóa công việc lập trình cũng như thêm vào những tính năng hữu dụng. Trong loạt bài này, tôi sẽ cho bạn biết về tiến trình được thực hiện bởi nhóm chuyện gia qua một vài tháng tới.

Trong bài đầu tiên, tôi sẽ đề cập đến 2 tính năng mà đã được thảo luận rất nhiều, sự tùy chọn Interface cho EJBs và Singleton Beans. Tôi sẽ cung cấp những tính năng có thể có để thảo luận. Nhớ rằng, chưa có cái nào là cuối cùng; Tất cả vẫn đang được làm việc bởi JCP, nó sẽ thay đổi sau khi nhận được những phản hồi từ cộng đồng khắp nơi trên thế giới.

Tùy chọn cho EJB Interfaces Thay đổi trước nhất mà nhóm chuyên gia đề cập đến là loại bỏ những trở ngại cuối cùng để làm cho EJBs trông giống với POJO hơn dưới hình thức đơn giản nhất bằng cách cho phép tùy chọn việc sử dụng Session Bean Interfaces.

Lập trình dựa trên Interface rõ ràng là một kỹ thuật hữu dụng để viết loosely-coupled, tăng khả năng test cho ứng dụng. Đó là lý do tại sao cả EJB 2.1 và Spring thúc đẩy ý tưởng các thành phần Interface. Trong thực tế (EJB3), luôn yêu cầu phải có ít nhất một cho EJB 3.0 Session Beans (Không yêu cầu cho Message Driven Beans).

Điều phiền toái là các Interface thì hiếm khi cần thiết trong nhiều trường hợp. Nhiều khi, chỉ cần một Java Object bình thường là đủ, đặc biệt khi bạn chả cần nhiều unit test hay loose-coupling trong ứng dụng của bạn.

EJB 3.1 cho phép bạn làm điều đó. Bây giờ bạn không cần bất kỳ Interfaces nào cho Session Beans, giống như Entities JPA và Message Driven Beans. Tất cả những gì bạn phải làm chú thích một POJO với @Stateless hay @Stateful để nhận được đầy đủ chức năng của EJB. Hãy xem ví dụ dưới đây được sửa đổi từ chương Session Bean trong EJB 3 in Action:

@Stateless
public class PlaceBidBean {
@PersistenceContext
private EntityManager entityManager;
public void placeBid (Bid bid) {
entityManager.persist(bid);
}
}

Tiếp tục với những thú vị, hãy thêm vào một vài tính năng :

@Stateless
@WebService
public class PlaceBidBean {
@PersistenceContext
private EntityManager entityManager;
@WebMethod
public void placeBid (Bid bid) {
entityManager.persist(bid);
}
}


Trong ví dụ trên, chúng ta đang sử dụng JAX-WS 2.0 để thông báo phương thức placeBid là một web service. Chúng ta cũng sử dụng JPA để persistent một Bid entity. PlaceBidBean có một loạt các tính năng sẵn có của Stateless Session Bean bao gồm : pooling, thread-safety, life-cycle, interceptors, security và declarative transactions. Trong ví dụ này có lẽ  bạn cũng đã biết nếu bạn đã quen thuộc với EJB 3.0, phương thức placeBid được bao bọc trong một trình quản lý giao tác JTA. Remoting dựa trên RMI cũng sẽ được hỗ trợ cho những bean này,

Singletons Beans ra đời:

EJB 3.1 Singleton Beans thì giống như GOF Signleton pattern. Trong bối cảnh Java EE, chúng chủ yếu được sử dụng để lưu trữ những dữ liệu được chia sẻ trên diện rộng.
Nhiều lần bạn cần phải cache một vài dữ liệu trong bộ nhớ mà không bắt database cứ phải truy vấn hoài. Stateless Session Beans hay Stateful Session Beans đều không đáp ứng được yêu cầu này. Trong khi Stateful Session Beans có thể được duy trì trên cache một session, nó thật sự không thể chia sẻ giữa các tầng ứng dụng dễ dàng được.
Có nhiều cách để giải quyết vấn đề này ngay bây giờ. Cách đơn giản nhất là sử dụng static fields hay GOF Singleton POJOs. Với những chiến lược phức tạp hơn, có thể làm việc xuyên qua những ứng dụng phân tán bao gồm sử dụng Servlet container application scope, JBOSS cache, OSCache, JCS và SwarmCache. Các giải pháp thương mại bao gồm Tangosol Coherence và Terracotta. Trong khi các giải pháp làm việc trong phần lớn thời gian, chúng có nhiều điểm yếu. Một vài cái thì không thread-safe (static fields, Singleton POJOs), một vài cái không hỗ trợ transactional (Singleton POJOs, Servlet với tầm vực Application, OSCache, JCS, Swarmcache), không cái nào có khả năng remotable và không có cái nào có cơ chế bảo mật. . Các giải pháp đơn giản hơn, dùng sản phẩm của third-party nhưng nó không chuẩn. Chúng ta hãy đến với EJB 3.1 Singletons.
Container sẽ bảo đảm để duy trì một thể hiện duy nhất cho EJB 3.1 Singleton. Có nghĩa là Singletons có thể cache các trạng thái xuyên qua tầng ứng dụng. Bởi vì nó là một EJB, Singletons có tất cả những dịch vụ trung gian mà bạn mong đợi –declarative transaction management, security, remoting, concurrency management, dependency injection, component life-cycle callbacks, interceptors và hơn thế nữa. Giống như tất cả những EJBs khác, Singleton là POJOs được chú thích đơn giản. Đây là một ví dụ :
@Singleton
public class DiscountRateBean {
@PersistenceContext
private EntityManager entityManager;
private Rate rate;

@PostConstruct
private void init() {
rate = entityManager.find(Rate.class, 1);
}

@PreDestroy
private void destroy() {
entityManager.merge(rate);
}

public void setRate(Rate rate) {
this.rate = rate;
}

public Rate getRate() {
return rate;
}

}


Ví dụ đang sử dụng JPA và bean life-cycle callbacks để tải dữ liệu lúc bắt đầu và lưu dữ liệu khi bean bị xóa bỏ (thông thường khi ứng dụng bị shut-down). Bất kỳ bean nào cọi getRate và setRate thì được bảo đảm truy cập để chia sẻ dữ liệu trong một thể hiện của DiscountRateBean. Bạn để ý một vấn đề thú vị --bất kỳ updates nào cũng sẽ bị mất nếu container không có cơ hội để gọi pre-destroy callback. Chúng ta sẽ thấy làm thế nào để tránh tối thiểu vấn đề này bằng cách sử dụng cron-like timers trong một bài viết sau này.

Mặc định, tất cả những phương thức Singleton thì được thread-safe và transactional. Có nghĩa là tất cả những truy cập đa luồng đến bean thì được Serialized và tất cả các phương thức được giả định có thuộc tính REQUIRED transaction attribute (bạn có nghĩ là một giá trị mặc định tốt không? Tại sao).

Bạn có thể thay đổi hành vi giao tác bằng cách sử dụng @TransactionManagement và @TransactionAttribute annotations giống như khi bạn làm cho Stateful hay Stateless Session Bean. Nếu bạn đã từng làm việc trên một dữ liệu lớn, bạn biết rằng Serialized cả setRate và getRate sẽ dẫn đến tình trạng thắt cổ chai một cách nghiêm trọng. Trong thực tế.bạn cần chỉ định một read-lock cho getRate trong khi read-write-lock thì dùng cho setRate. Bạn có thể làm điều này bằng @Concurrency như thế này:

@Singleton public class DiscountRateBean { @PersistenceContext private EntityManager entityManager; private Rate rate; @PostConstruct private void init() { rate = entityManager.find(Rate.class, 1); } @PreDestroy private void destroy() { entityManager.merge(rate); } @ConcurrencyAttribute(READ_WRITE_LOCK) public void setRate(Rate rate) { this.rate = rate; } @ConcurrencyAttribute(READ_LOCK) public Rate getRate() { return rate; }

}

Trong một vài ứng dụng việc chia sẻ dữ liệu chỉ là read-only. Locking nào sẽ không cần thiết nữa. Trong trường hợp này bạn có thể tạo một Singleton bất đồng bộ như thế này:

@Singleton
@ConcurrencyAttribute(NO_LOCK) // READ_LOCK would also work...
public class DiscountRateBean {

@PersistenceContext
private EntityManager entityManager;

private Rate rate;

@PostConstruct
private void init() {
rate = entityManager.find(Rate.class, 1);
}

public Rate getRate() {
return rate;
}

}



Một vài sự thay đổi trên thuộc các thuộc tính @ConcurrencyAttribute(READ_LOCK), @ConcurrencyAttribute(READ_WRITE_LOCK) và @ConcurrencyAttribute(NO_LOCK) được chuyển qua @ConcurrencyReadLock, @ConcurrencyReadWriteLock và @ConcurrencyNoLock. Các thuộc tính @TransactionAttribute sẽ chia thành @TransactionRequired, @RequiresNewTransaction, @TransactionNotSupported. Một số người đã chỉ ra rằng lối suy nghĩ này sẽ làm cho annotation phình to lên, và làm một bổ sung mới trở nên phức tạp. TÍnh chất của annotation này cũng không phù hợp với khai báo transations của Spring và C#.NET. Một số nhà tài trợ của mô hình này lại chỉ ra mô hình này lại dễ dàng hơn dùng @ConcurrencyAttribute(READ_WRITE_LOCK). Còn bạn, bạn nghĩ gì về điều này ?.

Bạn cũng có thể tự mình quản lý Singleton concurrency và muốn container sẽ không làm gì hơn là một dịch vụ trung gian. Nó được hỗ trợ thông qua cái được gọi là bean managed concurrency (tương tự như bean managed transactions). Đây là một ví dụ:

@Singleton @ConcurrencyManagement(BEAN) public class DiscountRateBean {

@PersistenceContext private EntityManager entityManager; private Rate rate; @PostConstruct private void init() { rate = entityManager.find(Rate.class, 1); } @PreDestroy private void destroy() { entityManager.merge(rate); } public synchronized void setRate(Rate rate) { this.rate = rate; } public synchronized Rate getRate() { return rate; } }


Lưu ý rằng lúc này bạn đang tự mình quản lý concurrency bằng cách sử dụng từ khóa synchronized. Vì container sẽ không can thiệp, bạn được tự do để sử dụng bất cứ cơ chế quản lý concurrency nào bạn thích, bao gồm không giới hạn sức mạnh của gói java.util.concurrent. Cho tới giờ, tính năng quản lý đồng thời thì giới hạn ở EJB3.1 singleton, nhưng chúng có thể được mở rộng qua những loại bean khác.

Singletons cũng cung cấp cho bạn cơ chế tải lazy/eager ngầm định.

EJB3.1 thêm những tính năng sau:

Hai tính năng được thảo luận ở đây là dựa vào tips của nhiều người. Có nhiều tính năng thú vị khác được liệt kê trong JSR. Dưới đây là những cái đặc biệt đáng chú ý:

  • Hỗ trợ trực tiếp sử dụng EJBs trong servlet container, bao gồm cả sự lựa chọn đóng gói đơn giản hơn, hiện nay có thể nghĩ là EJBs cho phép đặt ở trong thư mục WEB-INF/classes , tương tự cho phép ejb-jar.xml đặt bên trong thư mục WEB-INF(giống như file web.xml). Theo đó, bạn có thể đặt EJB jar trong thư mục WEB-INF/lib.
  • Cải tiến EJB Timer Service để hỗ trợ lập lịch dạng cron, tạo timer deployment-time, và Stateful Session Bean timed objects.
  • Hỗ trợ Stateful web services thông qua Stateful Session Bean web services endpoints.



Ngoài ra, còn một số tính năng hiện không nằm trong JSR, nhưng có thể rất tốt:

  • Tiếp tục đơn giản hóa JMS, JavaMail và database injected resources. Ví dụ, bạn có thể cắm MessageSenders vào Queues và ConnectionFactory. Gavin King quyết tâm rất lớn cho thành phần nâng cao này.
  • Một Service Provider Interface (SPI) cho EJB. Điều này có nghĩa sẽ thực hiện tích hợp một loạt các sáng tạo của bên thứ 3 như là iBATIS, Spring, ACEGI, Quartz hay thậm chí là Groovy Beans. Bill Burke, Mike Keigh và Reza Rahman sẽ hỗ trợ mạnh mẽ tính năng này.
  • Khả năng hỗ trợ cho EJB có thể chạy trên một container servlet hạng nhẹ như Tomcat. Nó tương tự những open source đã có trên thế giới như Embedded JBoss, OpenEJB và EasyBeans. Tính năng này sẽ thực hiện nếu bạn nghĩ rằng nó tốt.
  • Có thể sử dụng local transations hỗ trợ thêm cho JTA trong EJB. Tôi nghĩ nó hữu dụng cho những ứng dụng web nhỏ hơn mà thật sự không cần đến JTA.

(Lược dịch và tổng hợp từ internet)

About Langthang

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.
    Blogger Comment
    Facebook Comment

0 comments :

Post a Comment