InitialContext.doLookup调用Bean的构造函数两次

时间:2014-07-18 23:23:14

标签: java jboss ejb

我有一个名为RandomBean的SFSB,它有一个默认构造函数,@PostConstruct@PreDestroy@Remove方法。在构造函数中有一个简单的计数器。

@Stateful
public class RandomBean {

    public static int c = 0;

    public static final Logger logger = Logger.getLogger(RandomBean.class);

    private Random r;

    private int cc;

    public RandomBean() {
        c += 1;
        cc = c;
        r = new Random();
        logger.info("Random constructed: " + cc);
    }

    @PostConstruct
    public void init() {
        logger.info("Random started: " + cc);
    }

    public int nextInt() {
        logger.info("Random invoked: " + cc);
        return r.nextInt();
    }

    @PreDestroy
    public void destroy() {
        logger.info("Random destroyed: " + cc);
    }

    @Remove
    public void remove() {
        logger.info("removed: " + cc);
    }
}

我还有一个servlet,它对这个bean执行查找并调用它的nextInt方法。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    logger.info("Doing get");
    try {
        RandomBean r = InitialContext.doLookup("java:module/RandomBean");
        logger.info("get! " + r.nextInt());
        r.remove();
    } catch (NamingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

让我感到困惑的是,RandomBean的构造函数似乎被调用了两次:

02:13:09,558 INFO  [org.sokolas.model.HelloServlet] (http-localhost/127.0.0.1:8080-1) Doing get
02:13:09,559 INFO  [org.sokolas.model.RandomBean] (http-localhost/127.0.0.1:8080-1) Random constructed: 1
02:13:09,560 INFO  [org.sokolas.model.RandomBean] (http-localhost/127.0.0.1:8080-1) Random constructed: 2
02:13:09,561 INFO  [org.sokolas.model.RandomBean] (http-localhost/127.0.0.1:8080-1) Random started: 2
02:13:09,561 INFO  [org.sokolas.model.RandomBean] (http-localhost/127.0.0.1:8080-1) Random invoked: 2
02:13:09,562 INFO  [org.sokolas.model.HelloServlet] (http-localhost/127.0.0.1:8080-1) get! -2028573462
02:13:09,562 INFO  [org.sokolas.model.RandomBean] (http-localhost/127.0.0.1:8080-1) removed: 2
02:13:09,563 INFO  [org.sokolas.model.RandomBean] (http-localhost/127.0.0.1:8080-1) Random destroyed: 2

这种行为是否有意?我应该在@PostConstruct方法中进行所有初始化并且不使用构造函数吗? 我使用的是JBoss EAP 6.2。

1 个答案:

答案 0 :(得分:1)

容器可能决定预先创建bean实现的其他实例。 在实例创建时,它不受任何客户端会话的约束。

您应该将所有初始化逻辑放入ejbCreate / @ Init或@PostConstruct方法中。 如果你看一下SFSB在EJB 3.1规范4.6.1中可以做什么,你甚至会看到你不允许在构造函数中进行任何容器服务调用,但在回调中还有很多。