浏览 3140 次
锁定老帖子 主题:appfuse学习笔记(五)系统启动分析
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-31
最后修改:2010-03-18
Spring配置文件及applicationContext监听器的配置 …… <!-- Context Configuration locations for Spring XML files --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/applicationContext-resources.xml classpath:/applicationContext-dao.xml classpath:/applicationContext-service.xml classpath*:/applicationContext.xml /WEB-INF/applicationContext*.xml /WEB-INF/xfire-servlet.xml /WEB-INF/security.xml </param-value> </context-param> …… <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>com.mycompany.app.webapp.listener.StartupListener</listener-class> </listener> 2. ContextLoaderListener初始化applicationContext 当servlet容器启动时监听器ContextLoaderListener监听到ServletContextEvent事件,调用 contextInitialized方法 org.springframework.web.context.ContextLoaderListener private ContextLoader contextLoader; public void contextInitialized(ServletContextEvent event) { this.contextLoader = createContextLoader(); //初始化WebApplicationContext this.contextLoader.initWebApplicationContext(event.getServletContext()); } 在contextInitialized方法中调用了contextLoader的 initWebApplicationContext(event.getServletContext())方法 下面就来看contextLoader如何做的初始化 org.springframework.web.context.ContextLoader private WebApplicationContext context; public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException, BeansException { …… servletContext.log("Initializing Spring root WebApplicationContext"); …… try { …… this.context = createWebApplicationContext(servletContext, parent); …… return this.context; } …… } 启动tomcat时控制台中输出的 “信息:Initializing Spring root WebApplicationContext” 即为此时输出 在initWebApplicationContext方法中通过 createWebApplicationContext(servletContext, parent) 方法创建了WebApplicationContext context对象 再看如何创建的WebApplicationContext org.springframework.web.context.ContextLoader public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation"; protected WebApplicationContext createWebApplicationContext( ServletContext servletContext, ApplicationContext parent) throws BeansException { //使用serlcetContext从web.xml中得到配置的contextClass,如果没有则得到默认的contextClass Class contextClass = determineContextClass(servletContext); if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]"); } ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); …… //使用serlcetContext从web.xml中得到spring相关初始化配置参数 wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM)); …… return wac; } 再看如何得到的contextClass org.springframework.web.context.ContextLoader private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties"; private static final Properties defaultStrategies; static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. try { ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage()); } } public static final String CONTEXT_CLASS_PARAM = "contextClass"; protected Class determineContextClass(ServletContext servletContext) throws ApplicationContextException { //web.xml中没有配置contextClass,所以这里将得到空 String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM); if (contextClassName != null) { try { return ClassUtils.forName(contextClassName); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load custom context class [" + contextClassName + "]", ex); } } else { // contextClassName == null, 将执行这里的方法 contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName()); try { return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load default context class [" + contextClassName + "]", ex); } } } 这里首先会去web.xml中查找有无配置项,没有的话将从配置文件中读取配置项 从源码中可以看到配置文件设置为” ContextLoader.properties” 要读取的配置项为WebApplicationContext.class.getName() 找到org/springframework/web/context/ ContextLoader.properties # Default WebApplicationContext implementation class for ContextLoader. # Used as fallback when no explicit context implementation has been specified as context-param. # Not meant to be customized by application developers. org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext 所以最终在ContextLoaderListener中我们初始化得到的是XmlWebApplicationContext对象 3. StartupListener启动系统 当servlet容器启动时监听器StartupListener监听到ServletContextEvent事件,调用 contextInitialized方法 com.mycompany.app.webapp.listener.StartupListener public void contextInitialized(ServletContextEvent event) { log.debug("Initializing context..."); ServletContext context = event.getServletContext(); …… setupContext(context); } public static void setupContext(ServletContext context) { ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context); LookupManager mgr = (LookupManager) ctx.getBean("lookupManager"); // get list of possible roles context.setAttribute(Constants.AVAILABLE_ROLES, mgr.getAllRoles()); log.debug("Drop-down initialization complete [OK]"); } 下面先来看spring的配置 在applicationContext-service.xml中配置了bean “lookupManager” <bean id="lookupManager" class="com.mycompany.app.service.impl.LookupManagerImpl"> <property name="lookupDao" ref="lookupDao"/> </bean> 在applicationContext-dao.xml中配置了bean “lookupDao” <bean id="lookupDao" class="com.mycompany.app.dao.hibernate.LookupDaoHibernate"> <property name="sessionFactory" ref="sessionFactory"/> </bean> 同样在applicationContext-dao.xml中配置了bean “sessionFactory” <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> <property name="hibernateProperties"> <value> hibernate.dialect=${hibernate.dialect} hibernate.query.substitutions=true 'Y', false 'N' hibernate.cache.use_second_level_cache=true hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider </value> <!-- Turn batching off for better error messages under PostgreSQL --> <!-- hibernate.jdbc.batch_size=0 --> </property> </bean> 在这里指定了hibernate的配置文件和相关属性设置 <!—Hibernate SQL方言属性设置--> hibernate.dialect=${hibernate.dialect} <!—指定保存到数据库时true和false用Y和N代替 --> hibernate.query.substitutions=true 'Y', false 'N' <!—启用二级缓存--> hibernate.cache.use_second_level_cache=true <!—二级缓存的实现类--> hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider 然后在applicationContext-resources.xml中配置了bean “dataSource” <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="100"/> <property name="maxWait" value="1000"/> <property name="poolPreparedStatements" value="true"/> <property name="defaultAutoCommit" value="true"/> </bean> 这里使用了apache的dbcp来做的数据库连接池 配置文件先看到这里,回过头来再看 com.mycompany.app.webapp.listener.StartupListener public static void setupContext(ServletContext context) { ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context); LookupManager mgr = (LookupManager) ctx.getBean("lookupManager"); // get list of possible roles context.setAttribute(Constants.AVAILABLE_ROLES, mgr.getAllRoles()); log.debug("Drop-down initialization complete [OK]"); } 在这里得到了所有的角色,以备访问时使用 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-31
不错不错,楼主继续!
btw:我也喜欢savage garden,呵呵 |
|
返回顶楼 | |
发表时间:2009-07-31
已经配置好了appfuse,可以跑起来了,但是没有去研究源码,以你这份为参考资料了!继续!Come On!
|
|
返回顶楼 | |