Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
154 views
in Technique[技术] by (71.8m points)

java - How does the constructor of a class implementing JMS MDB actually work?

I am trying to understand the lifecycle of a JMS Message Driven Bean, specifically as it relates to the constructor of the Java class that is implementing it.

I have a class JMSClass that implements javax.jms.MessageListener so that I can have a Message Driven Bean with an onMessage() method that listens on a queue. The container of the MDB is a JBoss EAP 7.2 server. Here is a simplified and stripped down version of the class:

@ResourceAdapter(value = "wmq.jmsra.rar")
public class JMSClass implements MessageListener {

    private int x = 0;

    public JMSClass() {
        System.out.println("X: " + x);
    }

    @Override
    public void onMessage(Message message) {
        System.out.println("Value of x: " + ++x);
    }
}

x belongs to the bean instance, and x continues to increment successfully as onMessage() is called. Once I shut down and restart the JBoss instance, and therefore the bean instance, x returns to 0 and begins incrementing again. This is expected behaivor.

What is not expected is that the constructor gets called twice before onMessage() is called, and the value is always 0. So I end up with output that looks like this:

10:55:29,763 INFO  [stdout] (default-threads - 32) X: 0
10:55:29,861 INFO  [stdout] (default-threads - 32) X: 0
10:55:29,862 INFO  [stdout] (default-threads - 32) Value of x: 1
10:55:29,910 INFO  [stdout] (default-threads - 35) X: 0
10:55:29,910 INFO  [stdout] (default-threads - 35) X: 0
10:55:29,957 INFO  [stdout] (default-threads - 35) Value of x: 2
10:55:30,005 INFO  [stdout] (default-threads - 33) X: 0
10:55:30,005 INFO  [stdout] (default-threads - 33) X: 0
10:55:30,052 INFO  [stdout] (default-threads - 33) Value of x: 3
10:55:30,117 INFO  [stdout] (default-threads - 38) X: 0
10:55:30,117 INFO  [stdout] (default-threads - 38) X: 0
10:55:30,165 INFO  [stdout] (default-threads - 38) Value of x: 4
10:55:30,209 INFO  [stdout] (default-threads - 37) X: 0
10:55:30,209 INFO  [stdout] (default-threads - 37) X: 0
10:55:30,259 INFO  [stdout] (default-threads - 37) Value of x: 5
  1. If the constructor is called every time a message comes through onMessage(), I would expect the value of x to be set back to 0 each time (and why's it being called twice in the first place?)
  2. If x is incrementing with each message, then I would expect the constructor to only be called once in the beginning as the JBoss container instantiates the bean. From that point on, only the onMessage() code should be executing.

Can someone provide some insight on the lifecycle going on here and how the container instantiates an MDB? No resources I have found have mentioned the constructor in the MDB lifecycle.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The lifecycle of a MDB bean is described in the Chapter 5 of the EJB 3.2 spec

Basically the container calls the constructor, injects the dependencies and then calls a method with the @PostConstruct annotation if any. Then the bean is added to a pool to serve incoming messages.

It's important to note that any instance of the pool can serve an incoming message so you cannot rely on the value of x to count the messages.

As for the repeated call to the constructor this must be something implementation specific behavior of JBoss. May be it keeps adding instances to the pool. Maybe it creates some sort of dynamic proxy or subclass of the MDB for some reason... If you add methods to the MDB with the @PostConstruct and @PreDestroy annotation you could see if it's the former or not.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...