Version 3

    JBoss EJB 3.0 and Extensions

     

    &12488;&12524;&12452;&12523;&65299;&65306;&12475;&12483;&12471;&12519;&12531;Bean&12398;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&65288;Session Bean Life Cycle&65289;

     

    &12399;&12376;&12417;&12395;&65288;Introduction&65289;

     

    The EJB container creates and manages the session bean instances. But sometimes, you might need to customize the bean management process. For instance, you might want to assign initial values for field variables when the bean instance is created or close external resources when the bean instance is destroyed. To do this, you need to provide callback methods in the bean class for the EJB container to call at various stages of the bean life cycle.

     

    &12475;&12483;&12471;&12519;&12531;Bean&12398;&12452;&12531;&12473;&12479;&12531;&12473;&12399;&12289;EJB&12467;&12531;&12486;&12490;&12364;&29983;&25104;&12375;&31649;&29702;&12375;&12414;&12377;&12290;&12375;&12363;&12375;&26178;&25240;Bean&31649;&29702;&12434;&12459;&12473;&12479;&12510;&12452;&12474;&12375;&12383;&12356;&22580;&21512;&12418;&12354;&12427;&12391;&12375;&12423;&12358;&12290;&12383;&12392;&12360;&12400;&12289;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12398;&29983;&25104;&26178;&12395;&12289;&12354;&12427;&12501;&12451;&12540;&12523;&12489;&22793;&25968;&12395;&21021;&26399;&20516;&12434;&20195;&20837;&12375;&12383;&12426;&12289;&12354;&12427;&12356;&12399;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12364;&30772;&26820;&12373;&12428;&12427;&38555;&12395;&22806;&37096;&12522;&12477;&12540;&12473;&12398;&12463;&12525;&12540;&12474;&20966;&29702;&12434;&34892;&12387;&12383;&12426;&12375;&12383;&12356;&22580;&21512;&12364;&12354;&12427;&12391;&12375;&12423;&12358;&12290;&12371;&12398;&12424;&12358;&12394;&22580;&21512;&12399;&12289;Bean&12463;&12521;&12473;&12395;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12434;&29992;&24847;&12375;&12289;Bean&12398;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&12398;&12354;&12425;&12422;&12427;&22580;&38754;&12391;EJB&12467;&12531;&12486;&12490;&12395;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12434;&21628;&12403;&20986;&12373;&12379;&12427;&12371;&12392;&12364;&12391;&12365;&12427;&12398;&12391;&12377;&12290;

     

    In the old EJB 2.1, callback methods are inherited from framework interfaces. You have to implement them even if they are empty. That bloats the code and reduces the code readability. In EJB 3.0, there is no framework interfaces. You can simply annotate any method in the EJB class to make them life cycle callback methods. In this trail, we will explore those annotations.

     

    &21476;&12356;EJB 2.1&12391;&12399;&12289;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12399;&12501;&12524;&12540;&12512;&12527;&12540;&12463;&12398;&12452;&12531;&12479;&12501;&12455;&12540;&12473;&12363;&12425;&32153;&25215;&12375;&12390;&12356;&12414;&12375;&12383;&12290;&20966;&29702;&12364;&12394;&12367;&12390;&12418;&12289;&12371;&12428;&12425;&12398;&12452;&12531;&12479;&12501;&12455;&12540;&12473;&12434;&23455;&35013;&12377;&12427;&24517;&35201;&12364;&12354;&12426;&12414;&12375;&12383;&12290;&12371;&12428;&12391;&12399;&12467;&12540;&12489;&12399;&32933;&22823;&21270;&12375;&35501;&12415;&12395;&12367;&12367;&12394;&12387;&12390;&12375;&12414;&12356;&12414;&12377;&12290;EJB 3.0&12391;&12399;&12289;&12501;&12524;&12540;&12512;&12527;&12540;&12463;&12398;&12452;&12531;&12479;&12501;&12455;&12540;&12473;&12399;&12354;&12426;&12414;&12379;&12435;&12290;&31777;&21336;&12394;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12391;&12289;EJB&12463;&12521;&12473;&12398;&12393;&12398;&12513;&12477;&12483;&12489;&12391;&12418;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&12398;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12395;&12377;&12427;&12371;&12392;&12364;&12391;&12365;&12414;&12377;&12290;&12371;&12398;&12488;&12524;&12452;&12523;&12391;&12399;&12289;&12371;&12428;&12425;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12395;&12388;&12356;&12390;&23398;&12403;&12414;&12377;&12290;

     

    &12521;&12452;&12501;&12469;&12452;&12463;&12523;&12513;&12477;&12483;&12489;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&65288;Life cycle method annotations&65289;

     

    EJB 3.0 specification defines several annotations the bean can use to specify callback methods during the life cycle of the bean. The container automatically calls the annotated methods at different stages of the session bean life cycle. You can use the following annotations to tag any method in the bean class.

     

    EJB 3.0&12398;&20181;&27096;&12391;&12399;&12289;Bean&12398;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&12398;&20013;&12391;&21628;&12400;&12428;&12427;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12434;&25351;&23450;&12377;&12427;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12364;&12356;&12367;&12388;&12363;&23450;&32681;&12373;&12428;&12390;&12356;&12414;&12377;&12290;EJB&12467;&12531;&12486;&12490;&12399;&12289;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12373;&12428;&12383;&12513;&12477;&12483;&12489;&12434;&12475;&12483;&12471;&12519;&12531;Bean&12398;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&12398;&27096;&12293;&12394;&22580;&38754;&12391;&33258;&21205;&30340;&12395;&21628;&12403;&20986;&12375;&12414;&12377;&12290;&20197;&19979;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12399;&12289;Bean&12463;&12521;&12473;&12398;&12393;&12398;&12513;&12477;&12483;&12489;&12395;&12418;&20351;&29992;&12391;&12365;&12414;&12377;&12290;

     

    • @PostConstruct: The annotated method is called by the container immediately after a bean instance is instantiated. This annotation is applicable to both stateless and stateful session beans.

     

    • @PostConstruct: Bean&12452;&12531;&12473;&12479;&12531;&12473;&12364;&12452;&12531;&12473;&12479;&12531;&12473;&21270;&12373;&12428;&12383;&30452;&24460;&12395;&12371;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12364;&20184;&12356;&12383;&12513;&12477;&12483;&12489;&12364;&21628;&12403;&20986;&12373;&12428;&12427;&12290;&12473;&12486;&12540;&12488;&12524;&12473;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12418;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12418;&20351;&12360;&12427;&12290;

     

    • @PreDestroy: The annotated method is called before the container destroys an unused or expired bean instance from its object pool. This annotation is applicable to both stateless and stateful session beans.

     

    • @PreDestroy: &12458;&12502;&12472;&12455;&12463;&12488;&12503;&12540;&12523;&12363;&12425;&26399;&38480;&20999;&12428;&12420;&26410;&20351;&29992;&12398;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12364;&30772;&26820;&12373;&12428;&12427;&30452;&21069;&12395;&12371;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12364;&20184;&12356;&12383;&12513;&12477;&12483;&12489;&12364;&21628;&12403;&20986;&12373;&12428;&12427;&12290;&12473;&12486;&12540;&12488;&12524;&12473;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12418;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12418;&20351;&12360;&12427;&12290;

     

    • @PrePassivate: If a stateful session bean instance is idle for too long, the container might passivate it and store its state to a cache. The method tagged by this annotation is called before the container passivates the bean instance. This annotation is only applicable to stateful session beans.

     

    • @PrePassivate: &12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12364;&38263;&12356;&38291;&20351;&29992;&12373;&12428;&12394;&12356;&12392;&12289;&12467;&12531;&12486;&12490;&12399;&12452;&12531;&12473;&12479;&12531;&12473;&12434;&38750;&27963;&24615;&21270;&12375;&29366;&24907;&12434;&12461;&12515;&12483;&12471;&12517;&12395;&36864;&36991;&12377;&12427;&22580;&21512;&12364;&12354;&12427;&12290;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12364;&38750;&27963;&24615;&21270;&12373;&12428;&12427;&30452;&21069;&12395;&12371;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12364;&20184;&12356;&12383;&12513;&12477;&12483;&12489;&12364;&21628;&12403;&20986;&12373;&12428;&12427;&12290;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12398;&12415;&26377;&21177;&12290;

     

    • @PostActivate: When the client uses the passivated stateful session bean again, a new instance is created and the bean state is restored. The method tagged this annotation is called when the activated bean instance is ready. This annotation is only applicable to stateful session beans.

     

    • @PostActivate: &38750;&27963;&24615;&21270;&12373;&12428;&12383;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12434;&20877;&12403;&20351;&29992;&12377;&12427;&12392;&12289;&26032;&12383;&12395;&12452;&12531;&12473;&12479;&12531;&12473;&12364;&20316;&12425;&12428;&12289;Bean&12398;&29366;&24907;&12364;&24489;&20803;&12373;&12428;&12427;&12290;&26032;&12383;&12395;&24489;&20803;&12373;&12428;&12383;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12364;&20351;&29992;&21487;&33021;&12395;&12394;&12427;&12392;&12371;&12398;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12364;&20184;&12356;&12383;&12513;&12477;&12483;&12489;&12364;&21628;&12403;&20986;&12373;&12428;&12427;&12290;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12398;&12415;&26377;&21177;&12290;

     

    • @Init: This annotation designates initialization methods for a stateful session bean. It is different from the @PostConstruct annotation in that there can be multiple methods tagged with @Init in a stateful session bean. However, each bean instance can only have one @Init method invoked. The EJB 3.0 container determines which @Init method to invoke depending on how the bean is created (see the EJB 3.0 specification for details). The @PostConstruct method is called after the @Init method.

     

    • @Init: &12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12398;&21021;&26399;&21270;&12513;&12477;&12483;&12489;&12290;@PostConstruct&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12392;&12398;&36949;&12356;&12399;&12289;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12395;&12399;&35079;&25968;&12398;&12513;&12477;&12483;&12489;&12395;@Init&12434;&25351;&23450;&12391;&12365;&12427;&28857;&12391;&12354;&12427;&12290;&12375;&12363;&12375;&12289;&21508;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12391;&12399;@Init&12513;&12477;&12483;&12489;&12399;&65297;&22238;&12375;&12363;&21628;&12400;&12428;&12394;&12356;&12290;EJB 3.0&12467;&12531;&12486;&12490;&12364;&12393;&12398;@Init&12513;&12477;&12483;&12489;&12434;&21628;&12406;&12363;&12399;&12289;Bean&12398;&29983;&25104;&26041;&27861;&12395;&12424;&12387;&12390;&30064;&12394;&12427;&12290;&65288;&35443;&32048;&12399;EJB 3.0&12398;&20181;&27096;&12434;&21442;&29031;&12290;&65289;@Init&12513;&12477;&12483;&12489;&12398;&24460;&12289;@PostConstruct&12513;&12477;&12483;&12489;&12364;&21628;&12400;&12428;&12427;&12290;

     

    Another life cycle method annotation for stateful session bean is the @Remove tag. It is not a callback method since the application, not the container, calls the @Remove method on the bean stub to remove the bean instance in the container object pool.

     

    &12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12398;&12383;&12417;&12398;&12418;&12358;&19968;&12388;&12398;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&12513;&12477;&12483;&12489;&29992;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12399;@Remove&12479;&12464;&12391;&12377;&12290;&12381;&12428;&12399;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12391;&12399;&12354;&12426;&12414;&12379;&12435;&12290;&12394;&12380;&12394;&12425;&12289;&65288;&12467;&12531;&12486;&12490;&12391;&12394;&12367;&65289;&12450;&12503;&12522;&12465;&12540;&12471;&12519;&12531;&12364;&12467;&12531;&12486;&12490;&12398;&12458;&12502;&12472;&12455;&12463;&12488;&12503;&12540;&12523;&12363;&12425;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12434;&21066;&38500;&12377;&12427;&12383;&12417;&12395;&12289;@Remove&12513;&12477;&12483;&12489;&12434;&21628;&12403;&20986;&12377;&12363;&12425;&12391;&12377;&12290;

     

    &12469;&12531;&12503;&12523;&12450;&12503;&12522;&12465;&12540;&12471;&12519;&12531;&65288;The sample application&65289;

     

    In this trail, we further refactor the session-based calculator program to support session management. You are able to exit the current session and start a new one. You can also see how many sessions the calculator has served (i.e., unique visitors), how many are still active, and how many are passivated into the cache. Click on the following button to try the new calculator.

     

    &12371;&12398;&12488;&12524;&12452;&12523;&12391;&12399;&12289;&12475;&12483;&12471;&12519;&12531;&12434;&20351;&12387;&12383;&25237;&36039;&35336;&31639;&12503;&12525;&12464;&12521;&12512;&12395;&12289;&12475;&12483;&12471;&12519;&12531;&31649;&29702;&27231;&33021;&12434;&25345;&12388;&12424;&12358;&12395;&25913;&22793;&12375;&12390;&12415;&12414;&12375;&12423;&12358;&12290;&29694;&22312;&12398;&12475;&12483;&12471;&12519;&12531;&12434;&32066;&20102;&12375;&12289;&21029;&12398;&12475;&12483;&12471;&12519;&12531;&12434;&38283;&22987;&12375;&12390;&12415;&12390;&12367;&12384;&12373;&12356;&12290;&35336;&31639;&12503;&12525;&12464;&12521;&12512;&12364;&12475;&12483;&12471;&12519;&12531;&12434;&20966;&29702;&12375;&12383;&22238;&25968;&65288;&12388;&12414;&12426;&35370;&21839;&32773;&25968;&65289;&12289;&12381;&12398;&12358;&12385;&12398;&12450;&12463;&12486;&12451;&12502;&12394;&12475;&12483;&12471;&12519;&12531;&25968;&12289;&12461;&12515;&12483;&12471;&12517;&12395;&36864;&36991;&12373;&12428;&12383;&12475;&12483;&12471;&12519;&12531;&25968;&12394;&12393;&12364;&12431;&12363;&12427;&12399;&12378;&12391;&12377;&12290;&19979;&12398;&12508;&12479;&12531;&12434;&12463;&12522;&12483;&12463;&12375;&12390;&26032;&12375;&12356;&35336;&31639;&12503;&12525;&12464;&12521;&12512;&12434;&23455;&34892;&12375;&12390;&12415;&12390;&12367;&12384;&12373;&12356;&12290;

     

    @PostContruct&12398;&20363;&65288;The @PostContruct example&65289;

     

    The web layer of the application (e.g., the JSP page) requests a new stateful session bean stub at the beginning of a new session. In the container, that means a new bean instance is created. After the session bean construction, we first need to initialize the ArryList objects that store the history of the current session. Then, we should increase the unique visitor count and active session count in the static SessionRecord object by one. The initialize() method annotated with @PostContruct does exactly that.

     

    &12450;&12503;&12522;&12465;&12540;&12471;&12519;&12531;&12398;Web&23652;&65288;&12383;&12392;&12360;&12400;&12289;JSP&12506;&12540;&12472;&65289;&12399;&12289;&12475;&12483;&12471;&12519;&12531;&12398;&26368;&21021;&12391;&26032;&12383;&12394;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12434;&20316;&25104;&12375;&12414;&12377;&12290;&12388;&12414;&12426;&12289;&12467;&12531;&12486;&12490;&20869;&12391;&26032;&12383;&12394;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12364;&29983;&25104;&12373;&12428;&12414;&12377;&12290;&12475;&12483;&12471;&12519;&12531;Bean&12364;&29983;&25104;&12373;&12428;&12427;&12392;&12289;&12414;&12378;&12475;&12483;&12471;&12519;&12531;&12398;&23653;&27508;&12434;&20445;&25345;&12377;&12427;ArrayList&12458;&12502;&12472;&12455;&12463;&12488;&12434;&21021;&26399;&21270;&12375;&12414;&12377;&12290;&12381;&12375;&12390;&12289;&38745;&30340;&12394;SessionRecord&12458;&12502;&12472;&12455;&12463;&12488;&20869;&12398;&35370;&21839;&32773;&25968;&12392;&12289;&12450;&12463;&12486;&12451;&12502;&12394;&12475;&12483;&12471;&12519;&12531;&25968;&12434;&65297;&22679;&21152;&12375;&12414;&12377;&12290;&12371;&12428;&12425;&12398;&20966;&29702;&12399;&12289;@PostConstruct&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12434;&25351;&23450;&12375;&12383;initialize()&12513;&12477;&12483;&12489;&12364;&34892;&12356;&12414;&12377;&12290;

     

     @Stateful
     public class SessionCalculator implements Calculator, Serializable {
     
         // ... ...
         
         public ArrayList <Integer> starts, ends;
         public ArrayList <Double> growthrates, savings, results;
     
         @PostConstruct
         public void initialize () {
             starts = new ArrayList <Integer> ();
             ends = new ArrayList <Integer> ();
             growthrates = new ArrayList <Double> ();
             savings = new ArrayList <Double> ();
             results = new ArrayList <Double> ();
         
             SessionRecord.totalSess++;
             SessionRecord.activeSess++;
         }    
         
         // ... ...
     }
    

     

    @PrePassivate&12392;@PostActivate&12398;&20363;&65288;The @PrePassivate and @PostActivate example&65289;

     

    When the stateful session bean is passivated out of the memory, or activated back into the memory, we should update the active session count in the static SessionRecord object. The serialize() and activate() methods are two examples.

     

    &12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12364;&12513;&12514;&12522;&12363;&12425;&38750;&27963;&24615;&21270;&12373;&12428;&12427;&12392;&12365;&12392;&12289;&12513;&12514;&12522;&12395;&25147;&12373;&12428;&12427;&12392;&12365;&12289;&38745;&30340;&12394;SessionRecord&12458;&12502;&12472;&12455;&12463;&12488;&20869;&12398;&12450;&12463;&12486;&12451;&12502;&12394;&12475;&12483;&12471;&12519;&12531;&25968;&12434;&26356;&26032;&12377;&12427;&24517;&35201;&12364;&12354;&12426;&12414;&12377;&12290;&12371;&12398;&20966;&29702;&12399;serialize()&12513;&12477;&12483;&12489;&12392;activate()&12513;&12477;&12483;&12489;&12364;&34892;&12356;&12414;&12377;&12290;

     

     @Stateful
     public class SessionCalculator implements Calculator {
     
         // ... ...
         
         @PrePassivate
         public void serialize () {
             SessionRecord.pausedSess++;
         }
     
         @PostActivate
         public void activate () {
             SessionRecord.pausedSess--;
         }
           
         // ... ...
     }
    

     

    @PreDestroy&12398;&20363;&65288;The @PreDestroy example&65289;

     

    At the end of the session, the HttpSession object in the web layer expires and its cached stateful session bean stub is destroyed by the container. We reduce the count of active sessions via the @PreDestroy tagged exit() method.

     

    &12475;&12483;&12471;&12519;&12531;&12364;&32066;&20102;&12377;&12427;&12392;&12289;Web&23652;&12398;HttpSession&12458;&12502;&12472;&12455;&12463;&12488;&12399;&12420;&12364;&12390;&26399;&38480;&20999;&12428;&12392;&12394;&12426;&12289;&12461;&12515;&12483;&12471;&12517;&12373;&12428;&12390;&12356;&12427;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12399;&12467;&12531;&12486;&12490;&12363;&12425;&30772;&26820;&12373;&12428;&12414;&12377;&12290;@PreDestroy&12434;&25351;&23450;&12375;&12383;exit()&12513;&12477;&12483;&12489;&12391;&12289;&12450;&12463;&12486;&12451;&12502;&12394;&12475;&12483;&12471;&12519;&12531;&25968;&12434;&28187;&12425;&12375;&12414;&12377;&12290;

     

     @Stateful
     public class SessionCalculator implements Calculator {
     
         // ... ...
         
         @PreDestroy
         public void exit () {
             SessionRecord.activeSess--;
         } 
          
         // ... ...
     }
    

     

    @Remove&12398;&20363;&65288;The @Remove example&65289;

     

    When the application obtains a stateful session bean stub via JNDI at the beginning of a session, the server creates a new instance and places it into the pool. The session bean instance is automatically removed when the session expires. However, what if you want to start a new session before the current one expires? You can always explicitly call the @Remove annotated method to force the container to remove the bean instance. After the method call is completed, the EJB 3.0 container calls the @PreDestroy tagged method, if there is any, and removes the instance. In our example, the @Remove method is empty. It simply signals the container to remove this instance.

     

    &12450;&12503;&12522;&12465;&12540;&12471;&12519;&12531;&12364;&12475;&12483;&12471;&12519;&12531;&12398;&38283;&22987;&26178;&12395;JNDI&32076;&30001;&12391;&12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12398;&12473;&12479;&12502;&12434;&21462;&24471;&12377;&12427;&12392;&12289;&12469;&12540;&12496;&12399;&26032;&12375;&12356;&12452;&12531;&12473;&12479;&12531;&12473;&12434;&29983;&25104;&12375;&12289;&12503;&12540;&12523;&12395;&32622;&12365;&12414;&12377;&12290;&12475;&12483;&12471;&12519;&12531;Bean&12399;&12475;&12483;&12471;&12519;&12531;&12364;&26399;&38480;&20999;&12428;&12395;&12394;&12427;&12392;&33258;&21205;&30340;&12395;&21066;&38500;&12373;&12428;&12414;&12377;&12290;&12375;&12363;&12375;&12289;&26399;&38480;&12364;&20999;&12428;&12427;&21069;&12395;&26126;&31034;&30340;&12395;&21029;&12398;&12475;&12483;&12471;&12519;&12531;&12434;&38283;&22987;&12375;&12383;&12356;&22580;&21512;&12399;&12393;&12358;&12377;&12428;&12400;&33391;&12356;&12391;&12375;&12423;&12358;&65311;&12467;&12531;&12486;&12490;&12395;&24375;&21046;&30340;&12395;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12434;&21066;&38500;&12373;&12379;&12427;&12395;&12399;@Remove&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12391;&25351;&23450;&12375;&12383;&12513;&12477;&12483;&12489;&12434;&26126;&31034;&30340;&12395;&21628;&12403;&12414;&12377;&12290;&12513;&12477;&12483;&12489;&21628;&12403;&20986;&12375;&12364;&32066;&12431;&12427;&12392;&12289;EJB 3.0&12467;&12531;&12486;&12490;&12399;@PreDestroy&12513;&12477;&12483;&12489;&12364;&12354;&12428;&12400;&21628;&12403;&20986;&12375;&12289;&12452;&12531;&12473;&12479;&12531;&12473;&12434;&21066;&38500;&12375;&12414;&12377;&12290;&12371;&12398;&12469;&12531;&12503;&12523;&12391;&12399;&12289;@Remove&12513;&12477;&12483;&12489;&12399;&31354;&12391;&12377;&12290;&12513;&12477;&12483;&12489;&12399;&12467;&12531;&12486;&12490;&12395;&12452;&12531;&12473;&12479;&12531;&12473;&12434;&21066;&38500;&12377;&12427;&12424;&12358;&12395;&12471;&12464;&12490;&12523;&12434;&36865;&12427;&12384;&12369;&12391;&12377;&12290;

     

     @Stateful
     public class SessionCalculator implements Calculator {
     
         // ... ...
         
         @Remove
         public void stopSession () {
             // Call to this method signals the container
             // to remove this bean instance and terminates
             // the session.
         }
          
         // ... ...
     }
    

     

    The following code shows how the @Remove method is called in the JSP page. Note that we also empty the HttpSession cache to remove the invalid stub.

     

    &20197;&19979;&12398;&12467;&12540;&12489;&12399;JSP&12506;&12540;&12472;&12363;&12425;@Remove&12513;&12477;&12483;&12489;&12434;&21628;&12406;&20363;&12391;&12377;&12290;HttpSession&12398;&12461;&12515;&12483;&12471;&12517;&12434;&31354;&12395;&12375;&12289;&19981;&35201;&12394;&12473;&12479;&12502;&12434;&21066;&38500;&12377;&12427;&12371;&12392;&12395;&12418;&27880;&24847;&12375;&12390;&12367;&12384;&12373;&12356;&12290;

     

     // "cal" is the stub of the stateful session bean.
     // It is cached in the HttpSession's "lifecycle_cal" attribute
    
     // "cal"&#12399;&#12289;&#12473;&#12486;&#12540;&#12488;&#12501;&#12523;&#12475;&#12483;&#12471;&#12519;&#12531;Bean&#12398;&#12473;&#12479;&#12502;
     // HttpSession&#12398;"lifecycle_cal"&#23646;&#24615;&#12395;&#12461;&#12515;&#12483;&#12471;&#12517;&#12373;&#12428;&#12390;&#12356;&#12427;
    
     if ("Logout".equals(request.getParameter("action"))) {
       cal.stopSession ();
       session.setAttribute ("lifecycle_cal", null);
       
       // ... ...
     }
    

     

    &12521;&12452;&12501;&12469;&12452;&12463;&12523;&12513;&12477;&12483;&12489;&12434;&21029;&12463;&12521;&12473;&12395;&20998;&38626;&12377;&12427;&65288;Separate life cycle methods into another class&65289;

     

    If all those callback methods seem to clutter up your session bean class, you can also separate out the callback methods into a separate callback listener class. You need to annotate the session bean class with the @CallbackListener tag and specify the listener class name in the annotation parameter.

     

    &12371;&12428;&12425;&12377;&12409;&12390;&12398;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12434;&35352;&36848;&12377;&12427;&12392;&12475;&12483;&12471;&12519;&12531;Bean&12463;&12521;&12473;&12364;&20081;&38609;&12395;&12394;&12387;&12390;&12375;&12414;&12358;&22580;&21512;&12399;&12289;&12467;&12540;&12523;&12496;&12483;&12463;&12522;&12473;&12490;&12398;&12463;&12521;&12473;&12395;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12434;&20998;&38626;&12377;&12427;&12371;&12392;&12418;&12391;&12365;&12414;&12377;&12290;&12475;&12483;&12471;&12519;&12531;Bean&12463;&12521;&12473;&12395;@CallbackListener&12479;&12464;&12434;&25351;&23450;&12375;&12289;&12522;&12473;&12490;&12398;&12463;&12521;&12473;&21517;&12434;&12497;&12521;&12513;&12479;&12395;&35352;&36848;&12375;&12414;&12377;&12290;

     

     @Stateful
     @CallbackListener(CalculatorCallbackListener.class)
     public class SessionCalculator implements Calculator {
         // ... ...
     }
    

     

    The listener class contains all the annotated callback methods for this bean. Each callback method now takes the bean instance as input parameter. The container pasess the bean instance that causes the callback event to the callback method at runtime.

     

    &12522;&12473;&12490;&12463;&12521;&12473;&12395;&12399;&12289;&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12373;&12428;&12383;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12434;&12377;&12409;&12390;&35352;&36848;&12375;&12414;&12377;&12290;&12371;&12371;&12391;&12399;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12399;Bean&12452;&12531;&12473;&12479;&12531;&12473;&12434;&20837;&21147;&24341;&25968;&12395;&25345;&12385;&12414;&12377;&12290;{FOOTNOTE DEF 1 1}

     

    {FOOTNOTE RED #1 1} The container pasess the bean instance that causes the callback event to the callback method at runtime. &12364;&25244;&12369;&12390;&12414;&12377; -tokobayashi

     

     public class CalculatorCallbackListener {
     
         @PostConstruct
         public initialize (CalculatorBean cal) {
             // ... ...
         }
         
         @PreDestroy
         public exit (CalculatorBean cal) {
             // ... ...
         }
     
     }
    

     

    &12477;&12540;&12473;&12467;&12540;&12489;&21442;&29031;&65288;Complete code reference&65289;

     

    EJB&12469;&12540;&12496;&65288;EJB server&65289;

     

    • Calculator.java: The local business interface

    • SessionCalculator.java: The stateful session bean implementation

    • SessionRecord.java: The static object that holds various counters for served and active sessions

     

    • Calculator.java: &12525;&12540;&12459;&12523;&12499;&12472;&12493;&12473;&12452;&12531;&12479;&12501;&12455;&12540;&12473;

    • SessionCalculator.java: &12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12398;&23455;&35013;

    • SessionRecord.java: &20966;&29702;&12375;&12383;&12475;&12483;&12471;&12519;&12531;&25968;&12420;&12450;&12463;&12486;&12451;&12502;&12394;&12475;&12483;&12471;&12519;&12531;&25968;&12394;&12393;&12398;&12459;&12454;&12531;&12479;&12540;&12434;&25345;&12388;&38745;&30340;&12458;&12502;&12472;&12455;&12463;&12488;

     

    EJB&12463;&12521;&12452;&12450;&12531;&12488;&65288;EJB client&65289;

     

    • calculator.jsp: The client of the stateful calculator session bean

     

    • calculator.jsp: &12473;&12486;&12540;&12488;&12501;&12523;&12475;&12483;&12471;&12519;&12531;Bean&12398;&35336;&31639;&12503;&12525;&12464;&12521;&12512;&12398;&12463;&12521;&12452;&12450;&12531;&12488;

     

    &12414;&12393;&12417;&65288;Summary&65289;

     

    In this trail, we discussed the life cycles and callback methods for the session beans. JBoss's EJB 3.0 server not only manages session beans but also other types of service objects beyond the EJB 3.0 specification. In the next trail, we will discuss how to write a JMX Mbean service easily with JBoss annotations.

     

    &12371;&12398;&12488;&12524;&12452;&12523;&12391;&12399;&12289;&12475;&12483;&12471;&12519;&12531;Bean&12398;&12521;&12452;&12501;&12469;&12452;&12463;&12523;&12392;&12467;&12540;&12523;&12496;&12483;&12463;&12513;&12477;&12483;&12489;&12395;&12388;&12356;&12390;&35696;&35542;&12375;&12414;&12375;&12383;&12290;JBoss EJB 3.0&12469;&12540;&12496;&12399;&12289;&12475;&12483;&12471;&12519;&12531;Bean&12384;&12369;&12391;&12394;&12367;EJB 3.0&20181;&27096;&12395;&12399;&12394;&12356;&27096;&12293;&12394;&12479;&12452;&12503;&12398;&12469;&12540;&12499;&12473;&12458;&12502;&12472;&12455;&12463;&12488;&12418;&31649;&29702;&12375;&12414;&12377;&12290;&27425;&12398;&12488;&12524;&12452;&12523;&12391;&12399;&12289;JBoss&12450;&12494;&12486;&12540;&12471;&12519;&12531;&12434;&20351;&12387;&12390;&23481;&26131;&12395;JMX MBean&12469;&12540;&12499;&12473;&12434;&35352;&36848;&12377;&12427;&26041;&27861;&12395;&12388;&12356;&12390;&35696;&35542;&12375;&12414;&12375;&12423;&12358;&12290;

     

    (c) 2005 JBoss, Inc. All Rights Reserved