Spring启动流程解析-9-初始化主题

一,Spring启动流程概述

Spring的IoC容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段:

  • 容器启动阶段

  • Bean实例化阶段

容器初始化

  1. 加载配置

  2. 分析配置信息

  3. 将Bean信息装配到BeanDefinition

  4. 将Bean信息注册到相应的BeanDefinitionRegistry

  5. 其他后续处理

容器实例化

  1. 根据策略实例化对象

  2. 装配依赖

  3. Bean初始化前处理

  4. 对象初始化

  5. 对象其他处理

  6. 注册回调接口

二,Spring启动流程详解

初始化主题

protected void onRefresh() throws BeansException {
    // For subclasses: do nothing by default.
}

SpringMVC框架主题可以设置应用程序的整体外观,从而增强用户体验。主题是静态资源的集合,通常有css样式表和图片构成,这些css样式和图片会直接影响应用程序的视觉样式。

要在Web应用中使用主题,必须实现ThemeSource接口,WebApplicationContext接口就扩展了ThemeSource,但将其职责委托给专用的实现。

默认委托将是ResourceBundleThemeSource,该实现从类路径的根加载主题属性文件。要使用自定义ThemeSource或需要配置ResourceBundleThemeSource的属性,可以在应用程序上下文中注册使用保留名称'themeSource'的Bean,Web应用程序上下文会自动检测到具有'themeSource'名称的Bean并使用它。

主题使用示例

SpringMVC配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

	<mvc:default-servlet-handler />
	<mvc:annotation-driven  />

	<context:component-scan base-package="xxx.xxx" />

	<!-- 视图解析 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<!-- Theme主题资源 -->
	<bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
		<property name="basenamePrefix" value="theme." />
	</bean>

	<!-- Theme主题解析器 -->
	<bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver">
		<property name="defaultThemeName" value="blue" />
	</bean>

	<!-- Theme主题拦截器 -->
	<mvc:interceptors>
		<bean id="themeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
			<property name="paramName" value="theme" />
		</bean>
	</mvc:interceptors>
</beans>

主题资源文件

blue.properties和gray.properties两个属性配置文件存放到resources资源目录下面。

blue.properties

------------------------------
blue.properties
------------------------------
# css对应位置
styleSheet=/css/blue.css
# 图片对应位置
background=images/blue.png

gray.properties

------------------------------
gray.properties
------------------------------
# css对应位置
styleSheet=/css/gray.css
# 图片对应位置
background=images/gray.png

前端页面

JSP代码中引用主题文件的键。在JSP中,通常使用spring:theme标签来执行此操作,该标签与spring:message标签的使用方法非常相似。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<html>
<head>
<link rel="stylesheet" href="<spring:theme code='styleSheet'/>" type="text/css"/>
<title>Title</title>
</head>
<body style="background: url(<spring:theme code='background'/>)">
<a href="?theme=blue">blue</a> - <a href="?theme=gray">gray</a>
</body>
</html>

源码解析

public static ThemeSource initThemeSource(ApplicationContext context) {
    // 判断容器中是否包含"themeSource"的Bean
    if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
        // 如果包含则实例化这个themSource
        ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
        // 设置themeSource的父themeSource
        if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
            // 用来表示层级关系的ThemeSource对象
            HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
            if (hts.getParentThemeSource() == null) {
                hts.setParentThemeSource((ThemeSource) context.getParent());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using ThemeSource [" + themeSource + "]");
        }
        return themeSource;
    }
    else {
        // 如果context中不包含"themeSource"的定义
        HierarchicalThemeSource themeSource = null;
        // 如果context的parent是ThemeSource实例,则设置该contexnt的父ThemeSource
        if (context.getParent() instanceof ThemeSource) {
            // 实例化一个DelegatingThemeSource
            themeSource = new DelegatingThemeSource();
            themeSource.setParentThemeSource((ThemeSource) context.getParent());
        }
        else {
            // 否则,实例化一个ResourceBundleThemeSource
            themeSource = new ResourceBundleThemeSource();
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
                         "': using default [" + themeSource + "]");
        }
        return themeSource;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值