我有一个名为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。
答案 0 :(得分:1)
容器可能决定预先创建bean实现的其他实例。 在实例创建时,它不受任何客户端会话的约束。
您应该将所有初始化逻辑放入ejbCreate / @ Init或@PostConstruct方法中。 如果你看一下SFSB在EJB 3.1规范4.6.1中可以做什么,你甚至会看到你不允许在构造函数中进行任何容器服务调用,但在回调中还有很多。