Xpages @PreDestroy

2019-01-26 00:20发布

问题:

Summary: does anyone know how to get @PreDestroy to get triggered on recycling\ timeout of an Application Scope managed bean?

I posted a question a couple of weeks ago about "scheduled agents": 30 sec periodic task to poll external web service and cache data ...which I implemented successfully so far using a Thread (at present went with this method as all the logic contained within the design of the database), I can start\ cancel\ pause\ restart the Thread successfully from my Application Scope backing bean. But a side effect is that when the backing bean that initiates the Thread is recycled, the Thread keeps running. I have a method that calls my cancel Thread method using @PreDestroy in my Application Scope bean, but it appears this does not get called.

I did find this link from IBM: LO67255: MANAGED BEANS ANNOTATION - @POSTCONSTRUCT AND @PREDESTROY IS NOT WORKING AS EXPECTED. http://www-01.ibm.com/support/docview.wss?crawler=1&uid=swg1LO67255 ...but I do not have access to get to that article, so am not sure if the outcome is...it doesn't work.

I have a very simple test class to demonstrate, I imported some redundant libs at top, because of last post found here: https://community.jboss.org/thread/179819 but do not have access to javax.enterprise.* in XPages.

I set the "recycling" in the DB XPage properties "Application Timeout" to 1 for testing purposes. With a simple page calling (see below)...if you wait 1 min, you can see the constructor firing, but the @PreDestroy and PostConstruct never get called.

For any comments or suggestions...thanks in advance.

Nick

import javax.annotation.*;
import java.util.Date;
import javax.annotation.PreDestroy;

import javax.faces.context.*;
import javax.faces.lifecycle.*;


public class Junk {

    public Junk(){
        System.out.println("Junk.constructor()");
    }


    @PostConstruct
    public void afterOpen(){
        System.out.println("Junk.afterOpen() Resource after open...");
    }

    /**
     * 
     * @return
     */
    public String getJunkDate(){
        String res = "";
        Date d = new Date();
        try{

            System.out.println("Junk.getJunkDate()==e");

            res = d.toLocaleString();

        }catch(Exception e){
            e.printStackTrace();
        }
        return res;
    }


    @PreDestroy
    public void destroy(){
        System.out.println("Junk.destroy()...!");
    }

    public void finalize(){
        System.out.println("Junk.finalize()...!");
    }


}

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

    <xp:panel id="panel1">
        <xp:button value="Label" id="button1">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="partial" refreshId="panel1">
            </xp:eventHandler>
        </xp:button>
        <xp:br></xp:br>
        <xp:text escape="true" id="computedField1" value="#{javascript:Junk.junkDate}">
        </xp:text></xp:panel>
</xp:view>

回答1:

There are three types of JSF listener artifacts that provide an opportunity to manually clean up objects stored in scope (including managed beans):

  1. FacesContextListener: its beforeContextReleased() method is the absolute last call before any request terminates, so this is an ideal place to clean up the requestScope.
  2. SessionListener: its sessionDestroyed() method provides a chance to clean up the sessionScope.
  3. ApplicationListener: its applicationDestroyed() method provides a chance to clean up the applicationScope.

An ApplicationListener must be defined in an OSGi XSP Library; the first two can be defined either in a library or local to a specific NSF.



回答2:

I may be wrong, but XPages is built based on JSF1.2, while Managed bean annotations are available only from JSF2.0.



标签: xpages