myfaces的初始化是如何进行的
在看myfaces源码的时候,一直不明白javax.faces.webapp.FacesServlet中有一段
- public void init(ServletConfig servletConfig)
- throws ServletException
- {
- if(log.isTraceEnabled()) log.trace("init begin");
- _servletConfig = servletConfig;
- _facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
- //TODO: null-check for Weblogic, that tries to initialize Servlet before ContextListener
- //Javadoc says: Lifecycle instance is shared across multiple simultaneous requests, it must be implemented in a thread-safe manner.
- //So we can acquire it here once:
- LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
- _lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
- if(log.isTraceEnabled()) log.trace("init end");
- }
其中的FactoryFinder.getFactory是这样一段代码
- public static Object getFactory(String factoryName)
- throws FacesException
- {
- if(factoryName == null)
- throw new NullPointerException("factoryName may not be null");
- ClassLoader classLoader = getClassLoader();
- //This code must be synchronized because this could cause a problem when
- //using update feature each time of myfaces (org.apache.myfaces.CONFIG_REFRESH_PERIOD)
- //In this moment, a concurrency problem could happen
- Map factoryClassNames = null;
- Map<String, Object> factoryMap = null;
- synchronized(_registeredFactoryNames)
- {
- factoryClassNames = _registeredFactoryNames.get(classLoader);
- if (factoryClassNames == null)
- {
- throw new IllegalStateException(message);
- }
注意其中的 _registeredFactoryNames.get(classLoader),说明在javax.faces.webapp.FacesServlet之前_registeredFactoryNames已经构造好了,可是我查web.xml的时候,根本找不到其它类了,到底谁去初始化了_registeredFactoryNames呢?
其实是 WEB-INF/lib/myfaces-impl-1.2.6.jar 这个引入的包起了作用,这里面有2个.tld文件,tomcat等j2ee容器会扫描所有的classpath,遇到.tld文件,也会去里面执行的。在myfaces_core.tld中,除了定义了一些f:开头标签以外,就有一段监听器代码
- <listener>
- <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
- </listener>
这才是整个myfaces加载的爆炸点。以前struts的爆炸点都是在web.xml定义的servlet中的,这次放在了jar包里面,正是有点不习惯,要是仅仅想用里面的一些功能,还非得加载这个玩意了,呵呵。