Spring啟動流程(九)——初始化主題

努力的小強發表於2020-11-02
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="ai.yunxi" />

	<!-- 檢視解析 -->
	<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

前端頁面

<%@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;
    }
}

相關文章