学习Myfaces源码

来源:互联网 发布:c语言表示对数函数 编辑:程序博客网 时间:2024/04/29 16:56

最近想学习点东西,想来想去,打算看看myfaces的源码。都说看源码能学习到不少好东西。

首先从myfaces的启动开始,在web。xml配置文件中,我们回配置一个contextlistener, 

<listener>
       
<listener-class>
               org.apache.myfaces.webapp.StartupServletContextListener
      
</listener-class>
</listener>

这个listener对于整个myfaces的运行时时至关重要的,因为在这个license中,myfaces将读取系统中的配置文件

不只是WEB-INF下面的配置文件(下面将说道)。配置包括Application,ViewHandler等重要资源。

 

/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      
http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 
*/

package org.apache.myfaces.webapp;

import java.util.Iterator;
import java.util.List;

import javax.faces.FactoryFinder;
import javax.faces.context.ExternalContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.myfaces.config.FacesConfigValidator;
import org.apache.myfaces.config.FacesConfigurator;
import org.apache.myfaces.context.servlet.ServletExternalContextImpl;
import org.apache.myfaces.shared_impl.util.ClassUtils;
import org.apache.myfaces.shared_impl.util.StateUtils;
import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * <p>研发代号: <b>tea</b> </p>
 * 
 * <p>Title: ×××--×××--×××</p>
 * <p>Description: 系统启动加载</p>
 * <p>Copyright: Copyright (c) 2006  wangzj</p>
 * <p>Company: wangzj</p>
 * 
 * 创建时间 : 2006-10-26-9:00:44
 * 
@author 学习myfaces源码
 * 
@version $Revision: 1.0 $
 *
 
*/

public class StartupServletContextListener implements ServletContextListener {
    
private static final Log log = LogFactory
            .getLog(StartupServletContextListener.
class);
    
//猜测是标志位,判断是否faces_init已经进行
    static final String FACES_INIT_DONE = StartupServletContextListener.class
            .getName()
+ ".FACES_INIT_DONE";
    
/**
     * 监听函数
     
*/

    
public void contextInitialized(ServletContextEvent event) {
        System.out.println(
"##listener 监听启动。。。");
        initFaces(event.getServletContext());
    }

    
/**
     * 
     * 
@param servletContext servlet上下文
     
*/

    
public static void initFaces(ServletContext servletContext) {
        
try {
            
//判断是否facesContent已经init过
            Boolean b = (Boolean) servletContext.getAttribute(FACES_INIT_DONE);

            
if (b == null || b.booleanValue() == false{
                log.trace(
"Initializing MyFaces");

                
// Load the configuration , 
                
//初始化ServletExternalContextImpl的上下文,request,response等对象
                
//主要是设置request请求头中的charset(如果求求头中没有),
                
//但是改servlet因为是启动时记载,所以没有request,不做次处理,只是实例化servletContext
                ExternalContext externalContext = new ServletExternalContextImpl(
                        servletContext, 
nullnull);

                
// And configure everything
                new FacesConfigurator(externalContext).configure();

                
if ("true"
                        .equals(servletContext
                                .getInitParameter(FacesConfigValidator.VALIDATE_CONTEXT_PARAM))) 
{
                    List list 
= FacesConfigValidator.validate(externalContext,
                            servletContext.getRealPath(
"/"));

                    Iterator iterator 
= list.iterator();

                    
while (iterator.hasNext())
                        log.warn(iterator.next());

                }


                
// parse web.xml
                WebXml.init(externalContext);

                servletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
            }
 else {
                log.info(
"MyFaces already initialized");
            }

        }
 catch (Exception ex) {
            log.error(
"Error initializing ServletContext", ex);
            ex.printStackTrace();
        }

        log.info(
"ServletContext '" + servletContext.getRealPath("/")
                
+ "' initialized.");

        
if (servletContext.getInitParameter(StateUtils.INIT_SECRET) != null)
            StateUtils.initSecret(servletContext);

        handleSerialFactory(servletContext);
    }


    
private static void handleSerialFactory(ServletContext servletContext) {

        String serialProvider 
= servletContext
                .getInitParameter(StateUtils.SERIAL_FACTORY);
        SerialFactory serialFactory 
= null;

        
if (serialProvider == null{
            serialFactory 
= new DefaultSerialFactory();
        }
 else {
            
try {
                serialFactory 
= (SerialFactory) ClassUtils
                        .newInstance(serialProvider);

            }
 catch (ClassCastException e) {
                log.error(
"Make sure '" + serialProvider
                        
+ "' implements the correct interface", e);
            }
 catch (Exception e) {
                log.error(e);
            }
 finally {
                
if (serialFactory == null{
                    serialFactory 
= new DefaultSerialFactory();
                    log.error(
"Using default serialization provider");
                }

            }


        }


        log.info(
"Serialization provider : " + serialFactory.getClass());
        servletContext.setAttribute(StateUtils.SERIAL_FACTORY, serialFactory);

    }

    
/**
     * 监听函数
     
*/

    
public void contextDestroyed(ServletContextEvent e) {
        FactoryFinder.releaseFactories();
    }

}

 

可以发现在启动的时候系统进行了new FacesConfigurator(externalContext).configure();,进行配置,哈哈,这个可是很重要的,

 

public void configure() throws FacesException {
        
// These two classes can be easily replaced by alternative
        
// implementations.
        
// As long as there is no need to switch implementations we need no
        
// factory pattern to create them.
        
//初始化unmarshaller对象,作为xml操作的重要工具类,使用apache的digest
        _unmarshaller = 
            
new DigesterFacesConfigUnmarshallerImpl(_externalContext);
        
//初始化对象,主要用来装载系统一些对象集合,如下
        
//List applicationFactories = new ArrayList();
        
//List renderKitFactories = new ArrayList();
        _dispenser = new DigesterFacesConfigDispenserImpl();
        
/**
         * 该部分负责加载所有可能的xml配置文件中的配置信息到config中
         * 包括标准的xml配置,还有其他的jar中的配置等等
         
*/

        
try {
            
//加载stander_faces_config.xml,同时将解析的结果存入_dispenser
            feedStandardConfig();
            feedMetaInfServicesFactories();
            
// feedJarFileConfigurations();
            feedClassloaderConfigurations();
            feedContextSpecifiedConfig();
            feedWebAppConfig();
//加载web-inf下面的faces-cinfig.xml文件
        }
 catch (IOException e) {
            
throw new FacesException(e);
        }
 catch (SAXException e) {
            
throw new FacesException(e);
        }


        configureFactories();
        configureApplication();
        configureRenderKits();
        configureRuntimeConfig();
        configureLifecycle();
    }

看看吧加载了很多配置,myfaces用的时digester进行解析。