天天看點

使用PagePhaseListener觀察ADF生命周期的各個階段

1. 定義PagePhaseListener

import javax.faces.event.PhaseId;

import oracle.adf.controller.v2.lifecycle.Lifecycle;
import oracle.adf.controller.v2.lifecycle.PagePhaseEvent;
import oracle.adf.controller.v2.lifecycle.PagePhaseListener;

public class MyPagePhaseListener implements PagePhaseListener {

    public MyPagePhaseListener() {
        super();
    }

    public void beforePhase(PagePhaseEvent pe) {
        if (pe.getPhaseId() == 9)
            System.out.println("###### Processing new Request!");

        System.out.println("before - " + pe.getDebugValue() + " " + pe.getPhaseId());
    }

    public void afterPhase(PagePhaseEvent pe) {
        System.out.println("after - " + pe.getDebugValue() + " " + pe.getPhaseId());

        //if (pe.getPhaseId() == Lifecycle.PREPARE_RENDER_ID)
            
        if (pe.getPhaseId() == 14)
            System.out.println("###### Done with Request!\n");
    }
}
           

注意,這裡的參數對象類型是ADE中的PagePhaseEvent,而不是JSF中的PhaseEvent。

在實驗中,我發現,JSF的生命周期的各個階段的Id值分别對應到9至14,與PhaseId中的各個階段常量值不比對。

我感覺是一個設計上的缺陷,如果ADF能夠在Lifecycle類中重新定義ADF的生命周期的各個階段就好了。

2. 配置adf-settings.xml

使用PagePhaseListener觀察ADF生命周期的各個階段

(1)在ViewController項目下建立目錄META-INF,實際上就是在ViewController目錄下的src目錄下建立META-INF目錄。

(2)在META-INF目錄下建立adf-settings.xml,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<adf-settings xmlns="http://xmlns.oracle.com/adf/settings">
    <adf-controller-config xmlns="http://xmlns.oracle.com/adf/controller/config">
        <lifecycle>
            <phase-listener>
                <listener-id>myPagePhaseListener</listener-id>
                <class>view.pagephaselistener.MyPagePhaseListener</class>
            </phase-listener>
        </lifecycle>
    </adf-controller-config>
</adf-settings>
           

3. 開發一個基于ADF-BC的頁面

4. 運作頁面

在Server日志中,輸出如下結果:

###### Processing new Request!

before - jsfRestoreView 9

<_checkTimestamp> Apache Trinidad 正在啟用了時間戳檢查的情況下運作。這不應當在正式版環境中使用。請檢視 WEB-INF/web.xml 中的 org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION 屬性

after - jsfRestoreView 9

###### Processing new Request!

before - jsfRestoreView 9

after - jsfRestoreView 9

before - initContext 0

after - initContext 0

before - prepareModel 1

after - prepareModel 1

before - jsfRenderResponse 14

before - prepareRender 8

after - prepareRender 8

<_isBeanValidationAvailable> A Bean Validation provider is not present, therefore bean validation is disabled

after - jsfRenderResponse 14

###### Done with Request!

###### Processing new Request!

before - jsfRestoreView 9

after - jsfRestoreView 9

before - initContext 0

after - initContext 0

before - prepareModel 1

after - prepareModel 1

before - jsfApplyRequestValues 10

after - jsfApplyRequestValues 10

before - jsfProcessValidations 11

after - jsfProcessValidations 11

before - jsfUpdateModelValues 12

after - jsfUpdateModelValues 12

before - validateModelUpdates 5

after - validateModelUpdates 5

before - jsfInvokeApplication 13

after - jsfInvokeApplication 13

before - metadataCommit 7

after - metadataCommit 7

before - jsfRenderResponse 14

before - prepareRender 8

after - prepareRender 8

after - jsfRenderResponse 14

###### Done with Request!

可以看出,頁面第一次Load時,隻經曆了兩個大的階段:Restore_View和Render_Response。

點選Submit按鈕送出後,經曆了全部的階段。

另外,還注意到,在Render_Response階段,不是像我們想象的那樣先執行jsfRenderResponse,結束後再執行prepareRender。

而是prepareRender階段“嵌”在jsfRenderResponse中執行。

為了更好的觀察,ADF在各個階段都做了些什麼,修改ViewController項目的Debug參數,重新運作頁面。

使用PagePhaseListener觀察ADF生命周期的各個階段

這一次我們可以看出,在不同的階段ADF執行了很多不同的操作。

###### Processing new Request!

before - jsfRestoreView 9

after - jsfRestoreView 9

before - initContext 0

after - initContext 0

before - prepareModel 1

[392] Process BindingContainer state token(decompressed state):BCST:=0%V%=NEmployeesView1Iterator=-D-,

Refreshing binding container

[393] **** refreshControl() for BindingContainer :view_employeePageDef

[394] DCUtil, returning:oracle.jbo.uicli.binding.JUApplication, for AppModuleDataControl

[395] (oracle.adf.model.bc4j.DataControlFactoryImpl.SyncMode = Immediate

[396] Reusing a cached session application module instance

[397] Invoke refresh for :EmployeesView1Iterator

[398] Executing and syncing on IteratorBinding.refresh from :EmployeesView1Iterator

Attaching an iterator binding to a datasource

[399] Resolving VO:EmployeesView1 for iterator binding:EmployeesView1Iterator

Attaching an iterator binding to a datasource

Attaching an iterator binding to a datasource

Executing iterator binding

Executing iterator binding

Refreshing binding container

[400] Process BindingContainer state token(decompressed state):BCST:=0%V%=NEmployeesView1Iterator=-D-,

after - prepareModel 1

before - jsfApplyRequestValues 10

[401] view_employeePageDef: stop DC events

[402] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[403] view_employeePageDef: stop DC events

[404] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[405] view_employeePageDef: stop DC events

[406] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[407] view_employeePageDef: stop DC events

[408] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[409] view_employeePageDef: stop DC events

[410] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[411] view_employeePageDef: stop DC events

[412] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[413] view_employeePageDef: stop DC events

[414] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[415] view_employeePageDef: stop DC events

[416] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[417] view_employeePageDef: stop DC events

[418] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[419] view_employeePageDef: stop DC events

[420] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

[421] view_employeePageDef: stop DC events

[422] stopEvents on DataControl:AppModuleDataControl of frame:av4001e0l_1

after - jsfApplyRequestValues 10

before - jsfProcessValidations 11

after - jsfProcessValidations 11

before - jsfUpdateModelValues 12

Evaluate Expression

Evaluate Expression

after - jsfUpdateModelValues 12

before - validateModelUpdates 5

[423] DCBindingContainer:view_employeePageDef validating at level:all

Validate transaction

Validate Entity

Validate Entity

Validate Entity

Validate transaction

Validate transaction

after - validateModelUpdates 5

before - jsfInvokeApplication 13

after - jsfInvokeApplication 13

before - metadataCommit 7

after - metadataCommit 7

before - jsfRenderResponse 14

before - prepareRender 8

Refreshing binding container

[424] **** refreshControl() for BindingContainer :view_employeePageDef

Refreshing binding container

after - prepareRender 8

[425] EmployeeId: IGNORING Start events as it is not in active/push mode

[426] FirstName: IGNORING Start events as it is not in active/push mode

[427] LastName: IGNORING Start events as it is not in active/push mode

[428] Email: IGNORING Start events as it is not in active/push mode

[429] PhoneNumber: IGNORING Start events as it is not in active/push mode

[430] HireDate: IGNORING Start events as it is not in active/push mode

[431] JobId: IGNORING Start events as it is not in active/push mode

[432] Salary: IGNORING Start events as it is not in active/push mode

[433] CommissionPct: IGNORING Start events as it is not in active/push mode

[434] ManagerId: IGNORING Start events as it is not in active/push mode

[435] DepartmentId: IGNORING Start events as it is not in active/push mode

after - jsfRenderResponse 14

###### Done with Request!

參考文獻:

1. https://blogs.oracle.com/jdevotnharvest/entry/how_to_configure_an_adf_phase_listener_and_where_to_put_the_file

2. FOD Demo中的FODPhaseListener類。

3. 《Fusion Developer's Guide for Oracle Application Development

Framework》之How to Set Release Level in an ADF PagePhaseListener

ADF