最近想学习点东西,想来想去,打算看看myfaces的源码。都说看源码能学习到不少好东西。
首先从myfaces的启动开始,在web。xml配置文件中,我们回配置一个contextlistener,
<
listener
>
< listener-class >
org.apache.myfaces.webapp.StartupServletContextListener
</ listener-class >
</ 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, null, null);
// 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();
}
}
* 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, null, null);
// 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();
}
// 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进行解析。