`
SavageGarden
  • 浏览: 223254 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

appfuse学习笔记(五)系统启动分析

阅读更多
1. web.xml中的配置
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]");
}

在这里得到了所有的角色,以备访问时使用
分享到:
评论
2 楼 harbey 2009-07-31  
已经配置好了appfuse,可以跑起来了,但是没有去研究源码,以你这份为参考资料了!继续!Come On!
1 楼 popoer 2009-07-31  
不错不错,楼主继续!

btw:我也喜欢savage garden,呵呵

相关推荐

    appfuse学习笔记(一)安装部署

    **AppFuse 学习笔记(一):安装与部署** AppFuse 是一个开源项目,它提供了一种快速构建企业级 Web 应用程序的方式。它使用了多种流行的技术栈,如 Spring Boot、Hibernate、Thymeleaf 和 Maven,使得开发者可以更...

    appfuse 学习笔记

    ### Appfuse 学习笔记 #### 一、Appfuse 简介 Appfuse 是一个开源框架,旨在帮助开发者高效地构建企业级应用。通过提供一套完善的架构模板、最佳实践和技术栈组合,使得开发者能够专注于业务逻辑的实现,而不是...

    appfuse学习笔记(二)新建模块

    在本篇“appfuse学习笔记(二)新建模块”中,我们将深入探讨AppFuse框架的模块创建过程。AppFuse是一个开源项目,它提供了一个快速开发Web应用的基础结构,旨在简化开发流程并提高代码质量。通过AppFuse,开发者...

    AppFuse学习笔记(J2EE入门级框架)

    【AppFuse 框架详解】 AppFuse 是一个由 Matt Raible 创建的开源项目,它为初学者提供了一个基础的 J2EE 框架,用于演示如何集成多个流行的技术,如 ...AppFuse 不仅是一个框架,更是一个学习 J2EE 技术的良好起点。

    appfuse学习笔记(三)解决乱码和菜单设置

    在本篇“appfuse学习笔记(三)解决乱码和菜单设置”中,我们将深入探讨在使用AppFuse框架时遇到的编码问题以及如何定制应用程序的菜单。AppFuse是一款开源项目,它提供了一个快速开发Web应用的基础,特别是对于Java...

    AppFuse学习笔记

    总之,AppFuse 是一个强大的工具,它简化了 J2EE 应用的开发过程,特别是对于那些希望快速启动新项目并集成多种开源技术的开发者来说。通过本文的学习,读者将能够熟练运用 AppFuse,体验其带来的高效和便捷。同时,...

    appfuse

    通过理解和学习AppFuse的这些组件及其相互作用,你可以更好地掌握Java Web开发的基础,并且能够利用AppFuse快速创建自己的项目。对于初学者来说,这是一个很好的起点,而对于经验丰富的开发者,它则可以作为一个高效...

    AppFuse

    AppFuse是一个用于启动J2EE项目的工具包,它提供了一种快速而简便的方法来构建基于Java的应用程序。该工具包由Matt Raible创建,他在网络开发领域拥有丰富的经验,并且是多个开源项目的贡献者,包括Roller Weblogger...

    基于AppFuse框架的B2C电子商务系统研究与实现

    在本项目中,首先需要进行需求分析,明确B2C系统应有的功能模块,如用户注册登录、商品浏览、购物车、订单管理、支付接口集成等。然后,利用AppFuse的模板工程生成基本的项目结构,包括模型(Model)、视图(View)...

    appfuse2学习日记

    ### AppFuse2 学习知识点总结 #### 一、AppFuse 概述 - **定义与价值**:AppFuse 是一款开源项目,旨在利用一系列开源工具帮助开发者高效地搭建 Web 应用程序的基础架构。通过使用 AppFuse,开发人员可以在构建新...

    APPFUSE工具研究.doc

    AppFuse 是一个基于Java平台的开源项目,旨在加速和简化Web应用程序的开发。它通过集成各种流行框架,如Struts、Spring、Hibernate等,提供了一个...这对于快速启动新项目或学习现代Java Web开发技术是非常有价值的。

    可直接使用的appfuse项目

    AppFuse是一个集成了众多当前最流行开源框架与工具(包括Hibernate、ibatis、Struts、Spring、DBUnit、Maven、Log4J、Struts Menu、Xdoclet、SiteMesh、OSCache、JUnit、JSTL等(现在还有lucene的,无敌了))于一身的...

    appfuse1.4-architecture

    06年时的appfuse,学习SSH架构的经典入门框架。相对比较老的资料,可以欣赏一下当时的架构,向牛人致敬

    SSH学习及开发框架-appfuse

    appfuse 有struts2+hibernate+spring的整合 springmvc+hibernate+spring的整合 多模块,但模块都有 学习开发参考使用非常方便 可以到官方下载最新版的,我只是把自己下载的打包整理一下 注意哈,都是基于maven的...

    AppFuse项目研究

    AppFuse 是一个由 Matt Raible 创建的开源项目,旨在为...通过研究和使用 AppFuse,开发者不仅可以学习到如何整合这些流行的技术,还能了解到如何利用监听器进行初始化操作以及如何利用Spring进行依赖注入等最佳实践。

    MAVEN 搭建APPFUSE

    AppFuse是一个开源项目,旨在简化Web应用程序的开发,它提供了一个基础框架,可以帮助开发者快速启动新项目,整合了Spring、Hibernate、Struts等流行技术。在本教程中,我们将深入了解如何利用Maven这个强大的构建...

Global site tag (gtag.js) - Google Analytics