Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI

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@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ả:

Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI

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ả:

Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI

Lưu ý, annotation @PostConstruct@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ả:

Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI

Okay, Done!

Download code ví dụ trên tại đây

Code ví dụ Annotation @PostConstruct, @PreDestroy, @Any trong Java CDI

References:

https://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html

stackjava.com