Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI.
Mỗi CDI bean có một vòng đời, chúng ta có thể bắt được sự kiện khởi tạo và chuẩn bị hủy của mỗi bean đó bằng việc sử dụng 2 annotation @PostConstruct và @PreDestroy.
1. Annotation @PostConstruct
Thứ tự thực hiện khi khởi tạo 1 bean như sau:
- Đầu tiên CDI container sẽ gọi hàm khởi tạo (constructor) của bean (hàm khởi tạo mặc định hoặc hàm khởi tạo được đánh dấu @Inject)
- Tiếp theo CDI container sẽ khởi tạo giá trị cho các field được inject của bean
- Cuối cùng nếu có method được đánh dấu @PostConstruct nó sẽ được gọi.
Ví dụ:
package stackjava.com.cdidemo.dao; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; @Named("daoUtils") public class DAOUtils { private ConnectDatabase conn; public DAOUtils() { System.out.println("Constructor..."); } @Inject public void setConn(final ConnectDatabase conn) { System.out.println("setter"); this.conn = conn; } @PostConstruct public void init() { System.out.println("PostConstruct..."); } public void query() { conn.connect(); System.out.println("query database..."); } }
Demo:
package stackjava.com.cdidemo.main; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import stackjava.com.cdidemo.dao.DAOUtils; public class MainApp { public static void main(final String[] args) { Weld weld = new Weld(); WeldContainer container = weld.initialize(); BeanManager bm = container.getBeanManager(); Bean<DAOUtils> bean = (Bean<DAOUtils>) bm.getBeans("daoUtils").iterator().next(); CreationalContext<DAOUtils> ctx = bm.createCreationalContext(bean); DAOUtils daoUtils = (DAOUtils) bm.getReference(bean, DAOUtils.class, ctx); daoUtils.query(); } }
Kết quả:
2. Annotation @PreDestroy
Trái ngược với @PostConstruct, annotation @PreDestroy được sử dụng để đánh dấu method sẽ được gọi khi bean bị hủy.
Ví dụ:
package stackjava.com.cdidemo.dao; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Named; @Named("daoUtils") public class DAOUtils { private ConnectDatabase conn; public DAOUtils() { System.out.println("Constructor..."); } @Inject public void setConn(final ConnectDatabase conn) { System.out.println("setter"); this.conn = conn; } @PostConstruct public void init() { System.out.println("PostConstruct..."); } @PreDestroy public void destroy() { System.out.println("Destroy!"); } public void query() { conn.connect(); System.out.println("query database..."); } }
Demo:
package stackjava.com.cdidemo.main; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import stackjava.com.cdidemo.dao.DAOUtils; public class MainApp { public static void main(final String[] args) { Weld weld = new Weld(); WeldContainer container = weld.initialize(); BeanManager bm = container.getBeanManager(); Bean<DAOUtils> bean = (Bean<DAOUtils>) bm.getBeans("daoUtils").iterator().next(); CreationalContext<DAOUtils> ctx = bm.createCreationalContext(bean); DAOUtils daoUtils = (DAOUtils) bm.getReference(bean, DAOUtils.class, ctx); daoUtils.query(); ctx.release(); } }
Kết quả:
Lưu ý, annotation @PostConstruct và @PreDestroy chỉ áp dụng cho bean bị quản lý bởi CDI container, với các object được tạo bởi toán tử new sẽ không có tác dụng.
3. Annotation @Any
Annotation được dùng để injection tất cả các cài đặt của 1 interface.
Ví dụ:
package stackjava.com.cdidemo.dao; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.inject.Named; @Named("daoUtils") public class DAOUtils { public DAOUtils() { System.out.println("Constructor..."); } @Inject @Any private Instance<ConnectDatabase> allConnectType; @PostConstruct public void init() { System.out.println("PostConstruct..."); } @PreDestroy public void destroy() { System.out.println("Destroy!"); } public void query() { for (ConnectDatabase conn : allConnectType) { conn.connect(); } System.out.println("query database..."); } }
Demo:
package stackjava.com.cdidemo.main; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import stackjava.com.cdidemo.dao.DAOUtils; public class MainApp { public static void main(final String[] args) { Weld weld = new Weld(); WeldContainer container = weld.initialize(); BeanManager bm = container.getBeanManager(); Bean<DAOUtils> bean = (Bean<DAOUtils>) bm.getBeans("daoUtils").iterator().next(); CreationalContext<DAOUtils> ctx = bm.createCreationalContext(bean); DAOUtils daoUtils = (DAOUtils) bm.getReference(bean, DAOUtils.class, ctx); daoUtils.query(); ctx.release(); } }
Kết quả:
Okay, Done!
Download code ví dụ trên tại đây
Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI
References: