论坛首页 Java企业应用论坛

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

浏览 3140 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-07-31   最后修改:2010-03-18
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]");
}

在这里得到了所有的角色,以备访问时使用
   发表时间:2009-07-31  
不错不错,楼主继续!

btw:我也喜欢savage garden,呵呵
0 请登录后投票
   发表时间:2009-07-31  
已经配置好了appfuse,可以跑起来了,但是没有去研究源码,以你这份为参考资料了!继续!Come On!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics